简体   繁体   中英

Using strcat to add a whitespace onto a string literal?

Is there a way I can use strcat to add a trailing whitespace to a string literal? I'm reading stuff from a csv file and breaking it into tokens with strtok() then merging two different tokens with strcat but I want to do something so I create a whitespace between the two.

Here is an example of how my csv file reads:

"LastName, Firstname",ID
"LastName, Firstname",ID
"LastName, Firstname",ID

Here's my code:

char *firstname_token = NULL, *lastname_token = NULL, *ID_token, line[200];
for (i = 0; i < 3; i++){
fgets(line, 200, infile);
lastname_token = strtok(line," ");
firstname_token = strtok(NULL, ",");
ID_token=strtok(NULL," ");}

Currently firstname_token reads:

"Lastname,

Currently lastname_token reads:

Firstname"

I want to strcat (or something similar) them together in the form:

"Lastname, Firstname"

but retain that whitespace in between the two but I'm not sure how since I'm having to save them originally as string literals.

If your .csv file already contains the quoted field "Lastname, Firstname" , and that is what you need to parse from each line in the file, then there is no reason to split the lines on commas and then try and put the two halfs of the quoted field back together. Instead, simply locate the opening '"' saving a pointer to the start position within your line (say with char *start; ) and then locate the next '"' in the line saving a pointer to the end position in the line (say with char *end; ) and then simply copy from start to end into a new string (remembering to nul-terminate the new string)

This is made quite simple with the function strchr from string.h . Simply read each line into a buffer:

#define MAXC 256

int main (void) {

    char buf[MAXC],     /* buffer holding line */
        name[MAXC];     /* buffer to hold quoted lastname, firstname */

    while (fgets (buf, MAXC, stdin)) {          /* read each line */
        char *start, *end;                      /* start/end pointers */

Then locate the first double-quote within the line, and if found, save the address to the opening-quote in start :

        if ((start = strchr (buf, '"')))                /* if start " found */

if found, then find the ending '"' beginning your search at start + 1 and saving the address for the closing-quote in end , eg

            if ((end = strchr (start + 1, '"'))) {      /* if end " found */

finally, copy the entire quoted field to a new string (say name ),

                memcpy (name, start, end - start + 1);  /* copy to name */
                name[end - start + 1] = 0;              /* nul-terminate */

Putting together a short example that reads your .csv file as input on stdin (you can add the code to open the filename if you like), you could do:

#include <stdio.h>
#include <string.h>

#define MAXC 256

int main (void) {

    char buf[MAXC],     /* buffer holding line */
        name[MAXC];     /* buffer to hold quoted lastname, firstname */

    while (fgets (buf, MAXC, stdin)) {          /* read each line */
        char *start, *end;                      /* start/end pointers */
        if ((start = strchr (buf, '"')))                /* if start " found */
            if ((end = strchr (start + 1, '"'))) {      /* if end " found */
                memcpy (name, start, end - start + 1);  /* copy to name */
                name[end - start + 1] = 0;              /* nul-terminate */
                printf ("%s\n", name);          /* print captured name */
            }
    }

    return 0;
}

( note: to ensure a complete line of input fit in buf , you should check the final character read was '\\n' , which is left to you, but note, there is no guarantee that the final line in the file will contain a POSIX line-ending, so the second part of the check would be that strlen(buf) < MAXC - 1 . If either condition is satisfied, a complete line of text was read from the file)

Example Input File

Your input file with the addition of 1, 2, 3 following the names to distinguish the lines within the file:

$ cat dat/quoted.csv
"LastName1, Firstname1",ID
"LastName2, Firstname2",ID
"LastName3, Firstname3",ID

Example Use/Output

Compiling and running the code will save and output the quoted fields simply by copying the wanted characters, without having to tokenize or concatenate the pieces together.

$ ./bin/quotedfield < dat/quoted.csv
"LastName1, Firstname1"
"LastName2, Firstname2"
"LastName3, Firstname3"

There are a number of ways to do this, including simply working your way down your line buffer with a pointer and locating and counting '"' s, or using strcspn/strspn , etc.. Any way that can locate the surrounding quotes is fine. Then just copy from the opening-quote to the closing-quote into a new string, nul-terminate and you are done.

Let me know if you were attempting something other than capturing "LastName, Firstname" from each line in the file, or if you have further question about this approach instead of your strtok approach and I'm happy to help further.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM