首页 > 解决方案 > 使用 strcat 在字符串文字上添加空格?

问题描述

有没有一种方法可以strcat用来在字符串文字中添加尾随空格?我正在从csv文件中读取内容并将其分解为标记,strtok()然后合并两个不同的标记,strcat但我想做一些事情,所以我在两者之间创建了一个空格。

csv这是我的文件如何读取的示例:

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

这是我的代码:

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," ");}

目前firstname_token为:

"Lastname,

目前lastname_token为:

Firstname"

我想strcat(或类似的东西)以以下形式将它们放在一起:

"Lastname, Firstname"

但在两者之间保留那个空格,但我不确定如何,因为我必须将它们最初保存为字符串文字。

标签: cstringcsvwhitespace

解决方案


如果您的.csv文件已经包含引用的字段"Lastname, Firstname",并且这就是您需要从文件中的每一行解析的内容,那么没有理由拆分这些行commas然后尝试将引用字段的两半重新组合在一起。相反,只需找到开头'"'保存指向行中起始位置的指针(例如 with char *start;),然后找到'"'行中的下一个,保存指向行中结束位置的指针(例如 with char *end;),然后简单地从startto复制end到新字符串(记住以nul 终止新字符串)

strchr使用from函数可以很简单地做到这一点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 */

然后找到该行中的第一个双引号,如果找到,将地址保存到开头的引号中start

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

如果找到,则找到'"'开始搜索的结尾start + 1并将结束引号的地址保存在 中end,例如

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

最后,将整个引用字段复制到一个新字符串(比如name),

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

.csv将一个简短的示例放在一起,将您的文件作为输入读取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;
}

注意:为确保完整的输入行适合buf,您应该检查最终读取的字符是'\n',这是留给您的,但请注意,不能保证文件中的最后一行将包含 POSIX 行结尾,所以检查的第二部分是strlen(buf) < MAXC - 1. 如果满足任一条件,则从文件中读取一整行文本)

示例输入文件

您的输入文件添加了1, 2, 3以下名称以区分文件中的行:

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

示例使用/输出

编译和运行代码将通过复制所需的字符来保存和输出引用的字段,而无需将各个部分标记化或连接在一起。

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

有很多方法可以做到这一点,包括简单地使用指针沿着行缓冲区向下工作并定位和计数'"'s,或使用strcspn/strspn等。任何可以定位周围引号的方法都可以。然后只需从开头引号复制到结尾引号到一个新字符串中,nul-terminate 就完成了。

如果您尝试"LastName, Firstname"从文件中的每一行捕获以外的其他内容,或者您​​对这种方法而不是您的strtok方法有更多疑问,请告诉我,我很乐意提供进一步的帮助。


推荐阅读