让我们说我正在尝试解析的字符串为
“史密斯,约翰”,Data1,Data2,Data3
我还可以得到读为
的行Dave,Data1,Data2,Data3
所以我有if语句
line是文件中fgets()
的文本行,但是我认为这行得通
其余的我现在已经挣扎了大约一个小时左右。我正在尝试重新格式化“史密斯·约翰”,以便将其改成约翰·史密斯,然后将其分配给recTemp.artist
if (line[0] == '\"') {
//Read the last name, first name",
char lastTemp[30] = "";
char firstTemp[30] = "";
strcpy(lastTemp , strtok(line, ", "));
strcpy(firstTemp, strtok(NULL, "\","));
char * t;
t = strstr(lastTemp, "\"");
strcpy(t, " ");
//Concatenate each string assign to the artist value
strcat(firstTemp, lastTemp);
strcpy(recTemp.artist, firstTemp);
}
我认为错误来自于strstr调用或紧随其后的strcpy,但我不确定
谢谢!
答案 0 :(得分:0)
回答您的问题:
“我正在尝试重新格式化“约翰·史密斯”,以便重新命名为“约翰·史密斯””
使用正则表达式从字符串中提取引号的方法简短,我将执行以下操作,
#include <iostream>
#include <cstring>
#include <stdio.h>
int main() {
char line[100] = "\"Smith,John\",Data1,Data2,Data3";
// fgets(line, 100, stdin);
char* name = strtok(line, "\"");
char *substring2 = strtok(NULL, "\"");
char* LastName = strtok(name, ",");
char* FirstName = strtok(NULL, ",");
char result[100];
strcpy(result, FirstName);
strcat(result, ",");
strcat(result, LastName);
strcat(result, substring2);
printf("%s",result);
}
产生输出:
John,Smith,Data1,Data2,Data3
答案 1 :(得分:0)
如果要避免用line
更改strtok
,则可以简单地使用指针算法将"first last"
复制到recTemp.artist
,或将"name"
复制到第一个字段中没有引号的情况。这只是避免修改原始字符串的另一种方法。 (以及使用指针的健康锻炼)
如果存在引号,则可以将指针(p
)设置为line + 1
,然后使用strstr
查找子字符串"\","
并设置结束指针( endptr
)。然后,您可以使用strchar
在p
上调用','
,以找到last, first
之间的逗号,并设置另一个指针以前进到名字的开头(firstp
)。一旦firstp
指向名字的开头,您就可以将memcpy
的名字命名为recTemp.artist
,添加space
,然后复制姓氏,在此之后终止。
在不加引号的情况下,您只需使用strchr
来找到','
字段分隔符并调用memcpy
,然后以nul终止。
一个简短的例子是:
#include <stdio.h>
#include <string.h>
typedef struct {
char artist[64];
} rec_t;
int main (void) {
#ifndef NOQUOTE
char line[] = "\"Smith, John\",Data1,Data2,Data3";
#else
char line[] = "Dave,Data1,Data2,Data3";
#endif
rec_t recTemp;
if (*line == '\"') { /* if double-quotes are present */
char *p = line + 1, *endptr, *sep; /* ptr, endptr & sep */
if (!(endptr = strstr (p, "\","))) { /* find close quote, validate */
fputs ("error: invalid line format.\n", stderr);
/* handle error as needed, e.g. */
return 1;
}
if ((sep = strchr (p, ','))) { /* locate ',' in last, first */
char *firstp = sep + 1; /* set firstp to next char */
while (*firstp && *firstp == ' ') /* skip any leading spaces */
firstp++;
memcpy (recTemp.artist, firstp, endptr - firstp); /* copy first */
endptr = recTemp.artist + (endptr-firstp); /* set endptr after */
*endptr++ = ' '; /* add a space */
memcpy (endptr, p, sep - p); /* copy last */
*(endptr + (sep - p)) = 0; /* nul-terminate */
}
}
else { /* otherwise - name without quotes */
char *sep = strchr (line, ','); /* find field seperator */
if (!sep) {
fputs ("error: invalid line format.\n", stderr);
/* handle error as needed, e.g. */
return 1;
}
memcpy (recTemp.artist, line, (sep - line)); /* copy name */
*(recTemp.artist + (sep - line)) = 0; /* nul-terminate */
}
printf ("recTemp.artist: '%s'\n", recTemp.artist);
}
使用/输出示例
$ ./bin/rectmp
recTemp.artist: 'John Smith'
使用-DNOQUOTE
编译的未加引号的姓名大小写:
$ ./bin/rectmpnq
recTemp.artist: 'Dave'
无论您使用strtok
还是沿line
向下移动几个指针,都可以。如果要保留未经修改的line
,请在使用strtok
对副本进行操作之前进行复制,或者仅使用指针算法。您可以转储在两个方法上生成的程序集,以查看编译器是否在两个方法之间提供了优化优势。在事物的宏伟计划中,这种差异可以忽略不计。