简体   繁体   English

使用strcat在字符串文字上添加空格?

[英]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? 有没有一种方法可以使用strcat将尾随空格添加到字符串文字中? 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. 我正在从csv文件中读取内容,并使用strtok()将其分解为令牌,然后将两个不同的令牌与strcat合并,但是我想做一些事情,因此在两者之间创建了空白。

Here is an example of how my csv file reads: 这是我的csv文件读取方式的示例:

"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: 当前firstname_token读取:

"Lastname,

Currently lastname_token reads: 当前lastname_token读取:

Firstname"

I want to strcat (or something similar) them together in the form: 我想strcat (或类似的东西)在一起的形式:

"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. 如果您的.csv文件已经包含带引号的字段"Lastname, Firstname" ,而这就是您需要从文件中的每一行中进行解析的内容,那么就没有理由将commas为两行,然后尝试将两半引用的字段一起返回。 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) 取而代之的是,只需找到开头'"'将指针保存到行中的开始位置(例如使用char *start; ),然后在行中找到下一个'"' ,将指针保存至行中的结束位置(例如与char *end; ),然后简单地复制从startend为一个新的字符串(记住要NUL,终止新的字符串)

This is made quite simple with the function strchr from string.h . 使用来自string.h的函数strchr ,这非常简单。 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 : 然后在该行中找到第一个双引号,如果找到,则将地址保存到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 如果找到,则查找结束'"'开始您在搜索start + 1并保存地址在最后引号end ,如

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

finally, copy the entire quoted field to a new string (say name ), 最后,将整个带引号的字段复制到新字符串(例如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: 放一个简短的示例,将您的.csv文件读取为stdin上的stdin (您可以添加代码以打开文件名),可以这样做:

#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) 注意:为确保完整的输入行适合buf ,应检查读取的最终字符为'\\n' ,但这要留给您,但请注意,不能保证文件中的最后一行将包含POSIX行尾,因此检查的第二部分将是strlen(buf) < MAXC - 1 。如果满足任一条件,将从文件中读取一行完整的文本)

Example Input File 输入文件示例

Your input file with the addition of 1, 2, 3 following the names to distinguish the lines within the file: 输入文件的名称后要加上1, 2, 3以区分文件中的各行:

$ 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. 有很多方法可以做到这一点,包括简单地使用指针在行缓冲区中向下移动并定位和计数'"'或使用strcspn/strspn等。任何可以找到周围引号的方法都可以然后,只需将开头引号复制到结尾引号复制到新字符串中,然后以nul-terminate结束即可。

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. 让我知道您是否正在尝试从文件的每一行中捕获"LastName, Firstname" ,还是您对这种方法而不是strtok方法还有其他疑问,我们很乐意为您提供进一步的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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