0

我正在尝试遍历字符串并划分由制表符分隔的单词。

if(argc == 1) {
    while (argc == 1) {
        scanf("%s", ent);
        printf("<tr>");
        while (sscanf(ent, "%[^\t]%n", piece, &n) == 1 ) {           
            printf("<td>%s</td>", piece);
            ent += n;
        }
        printf("</tr>");
    }
}

当我运行这段代码而不是<tr><td>a</td><td>b</td><td>c</td></tr><tr><td>a</td></tr><tr><td>b</td></tr><tr><td>c</td></tr> 给标准输入 a\tb\tc\n 时得到的,这意味着在内部 while 循环结束并且外部循环运行一次之后位置会发生变化。内部while循环不应该遍历所有字符串吗?我只能使用sscanfstrtol作为字符串遍历分隔符。

4

3 回答 3

1

如果您尝试对字符串进行标记,请使用strtok(3)而不是:sscanf(3)

char *piece = strtok(ent, "\t");
while (piece)
{
    printf("<td>%s</td>", piece);
    piece = strtok(NULL, "\t");
}

您可能也应该使用fgets(3)而不是scanf(3)获取字符串输入。

于 2013-10-28T20:16:33.117 回答
0

这是因为您没有跳过选项卡。 %[^\t]%n将跨越所有非制表符并计算它们,然后ent += n将跳过这些,然后您将在制表符处重新启动。

忽略前导空格更容易(而且使用 html 这根本不是一件坏事):

while (sscanf(ent, " %[^\t]%n", piece, &n) == 1 )
//                  ^ skip spaces
        printf("<td>%s</td>",piece);
        ent += n;
}

或者如果由于某种原因你必须有一个完整的终止标签,

while (sscanf(ent,"[^\t]%n", piece, &n) ==1) {
        printf("<td>%s</td>",piece);
        ent+=n;
        if (*ent) ++ent;
}

如果周围没有过分挑剔的学究,这很有用:

int scanned=0;
while ( sscanf( ent+=scanned,"%[^\t]%n%*c%n", piece, &scanned, &scanned) > 0 )
        printf("<td>%s</td>",piece);

不要听那些不喜欢的人%n,他们只是%n空谈者:-)

于 2013-10-29T01:55:06.510 回答
0

scanf("%s"读取一个空格分隔的字符串——所以在你的例子中,第一个调用读取字符串a(当它看到选项卡时停止——空格)。如果您想读取整行(空白和所有),请fgets改用。

于 2013-10-28T22:35:38.357 回答