sscanf解析疑问 [英] sscanf parsing doubt

查看:52
本文介绍了sscanf解析疑问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在解析一个CSV文件。

我想把每一行读成一个合理大小的字符数组然后

从中提取字符串。

< snippet>

char foo [128] =" hello,world,bye,bye,world" ;;

.....

sscanf(foo,"%s%* [,]%s%* [,]%s%* [,]%s%* [, ]%s",s1,s2,s3,s4,s5);

< snippet />

这给了我垃圾。

我明白它没有找到''\ 0''来扫描(%s)字符串。

然后我也不能使用%c。

我认为我可以像%64c%* [,]%64c那样使用。

请告诉我这里使用的算法。我是这样做的吗?

正确的方式?


在此先感谢,

Simone Mehta。

-

生活大号。

hi All,
I am parsing a CSV file.
I want to read every row into a char array of reasonable size and then
extract strings from it.
<snippet>
char foo[128]="hello,world,bye,bye,world";
.....
sscanf(foo,"%s%*[,]%s%*[,]%s%*[,]%s%*[,]%s",s1,s2,s3,s4,s5);
<snippet/>
This is giving me junk .
I understand it is not finding ''\0'' to scan (%s) strings.
but then I cannot use %c also .
I think i can use like "%64c%*[,]%64c" .
Please enlighten me as to the algo to be used here . Am i doing it the
right way ?

Thanks In Advance,
Simone Mehta.

--
live life Queen Size.

推荐答案


< snippet>
char foo [128] =" hello,world,bye,bye,world" ;;
....
sscanf(foo," %s%* [,]%s%* [,]%s%* [,]%s%* [,]%s",s1,s2,s3,s4,s5);
< snippet />
这给了我垃圾。
我知道它没有找到''\ 0''来扫描(%s)字符串。


不。它给你垃圾,因为%s从白色空间跨越到白色空间
。逗号不是空格,所以s1可以全部使用。


检查scanf()的返回值,这会告诉你实际输入的项目有多少?可以阅读。


使用scanset:例如,你可以扫描%[^,\ t]

,它停在第一个逗号,空白或制表符。


然后我也不能使用%c。
我想我可以像%64c%* [,]%64c那样使用。
<snippet>
char foo[128]="hello,world,bye,bye,world";
....
sscanf(foo,"%s%*[,]%s%*[,]%s%*[,]%s%*[,]%s",s1,s2,s3,s4,s5);
<snippet/>
This is giving me junk .
I understand it is not finding ''\0'' to scan (%s) strings.
Nope. It gives you junk because %s spans from white space to
white space. Commas are not white spaces, so s1 gets it all.

Check the return value of scanf(), this tells you how many
input items you actually could read.

Use the scanset: For example, you can scan for "%[^, \t]"
which stops at the first comma, blank or tabulator.

but then I cannot use %c also .
I think i can use like "%64c%*[,]%64c" .




编号c转换说明符不会给你字符串

但字符数组可能很难处理。

除此之外,逗号被吞噬的问题

%64c仍然存在。

除此之外,使用字段宽度读取

存储在s1到s5中的字符串是一个好主意。

如果最后一项之前的字符串太长,返回值

scanf会告诉你。对于最后一项,请在新闻组中查看

Pop'的设备,了解如何获得

摆脱其余部分。

干杯

Michael

#include< stdio.h>

#include< stdlib.h>

#define MAXITEMLEN 32

#define STRINGIZE(s)#s

#define XSTR(s)STRINGIZE(s)
< br $>
#define DONTSCAN",\t"

#define ITEMFORMAT" [^ DONTSCAN"]"

#define MAXITEMFORMAT XSTR(MAXITEMLEN)ITEMFORMAT


#define ONEITEM"%" MAXITEMFORMAT

#define SEP"%* [" DONTSCAN""


int main(无效)

{

char foo [128] ="你好,世界,再见,\ tbye \ t,世界" ;;

char s0 [MAXITEMLEN],s1 [MAXITEMLEN],s2 [MAXITEMLEN];

char s3 [MAXITEMLEN ],s4 [MAXITEMLEN];

int rv;


rv = sscanf(foo,"" ONEITEM SEP ONEITEM SEP ONEITEM SEP

ONEITEM SEP ONEITEM,s0,s1,s2,s3,s4);


开关(rv){

案例5:

fprintf(stdout," s4:%s \ n",s4);

案例4:

fprintf(stdout," s3: %s \ n",s3);

案例3:

fprintf(stdout," s2:%s \ n",s2);

案例2:

fprintf(stdout," s1:%s \ n",s1);

案例1:

fprintf(stdout," s0:%s \ n",s0);

默认值:

if(rv!= 5){

fprintf(stderr,没有得到所有物品!\ n);

退出(EXIT_FAILURE);

}

}

返回0;

}



No. The c conversion specifier will not give you strings
but character arrays which can be nasty to handle.
Apart from that, the problem of the comma being gobbled
by %64c still persists.
Apart from that, using a field width for reading in the
strings to be stored in s1 through s5 is a Good Idea.
If a string before the last item was too long, the return value
of scanf will tell you. For the last item, look up
Pop''s Device here in the newsgroup to see how to get
rid of the rest of the line.
Cheers
Michael
#include <stdio.h>
#include <stdlib.h>
#define MAXITEMLEN 32

#define STRINGIZE(s) # s
#define XSTR(s) STRINGIZE(s)

#define DONTSCAN ", \t"
#define ITEMFORMAT "[^" DONTSCAN "]"
#define MAXITEMFORMAT XSTR(MAXITEMLEN) ITEMFORMAT

#define ONEITEM "%" MAXITEMFORMAT
#define SEP "%*[" DONTSCAN "]"

int main (void)
{
char foo[128] = "hello,world, bye ,\tbye\t,world";
char s0[MAXITEMLEN], s1[MAXITEMLEN], s2[MAXITEMLEN];
char s3[MAXITEMLEN], s4[MAXITEMLEN];
int rv;

rv = sscanf(foo, " " ONEITEM SEP ONEITEM SEP ONEITEM SEP
ONEITEM SEP ONEITEM, s0, s1, s2, s3, s4);

switch (rv) {
case 5:
fprintf(stdout,"s4: %s\n",s4);
case 4:
fprintf(stdout,"s3: %s\n",s3);
case 3:
fprintf(stdout,"s2: %s\n",s2);
case 2:
fprintf(stdout,"s1: %s\n",s1);
case 1:
fprintf(stdout,"s0: %s\n",s0);
default:
if (rv != 5) {
fprintf(stderr, "Did not get all items!\n");
exit(EXIT_FAILURE);
}
}
return 0;
}


Simone Mehta写道:
Simone Mehta wrote:

大家好,
我正在解析一个CSV文件。
我想把每一行读成一个大小合理的字符串数组然后从中提取字符串它。
< snippet>
char foo [128] =" hello,world,bye,bye,world" ;;
....
sscanf(foo," ;%s%* [,]%s%* [,]%s%* [,]%s%* [,]%s",s1,s2,s3,s4,s5);
< snippet />
这给了我垃圾。
我知道它没有找到''\ 0''来扫描(%s)字符串。
但是我不能使用%c还有。
我想我可以像%64c%* [,]%64c那样使用。
请告诉我这里使用的算法。我这样做是对吗?

hi All,
I am parsing a CSV file.
I want to read every row into a char array of reasonable size and then
extract strings from it.
<snippet>
char foo[128]="hello,world,bye,bye,world";
....
sscanf(foo,"%s%*[,]%s%*[,]%s%*[,]%s%*[,]%s",s1,s2,s3,s4,s5);
<snippet/>
This is giving me junk .
I understand it is not finding ''\0'' to scan (%s) strings.
but then I cannot use %c also .
I think i can use like "%64c%*[,]%64c" .
Please enlighten me as to the algo to be used here . Am i doing it the
right way ?




我认为最简单的方法是从文件中读取整行

到字符串,然后处理内存中的字符串。


/ *来自new.c的BEGIN输出* /


helloworldbyebyeworld

/ *来自new.c的END输出* /

/ * BEGIN new.c * /


#include< stdio.h>

#include< string.h>


int main(无效)

{

char foo [128] =" hello,world,bye,bye,world" ;;

char * pointer;


for(pointer = foo; * pointer!=''\'''; ++指针){

if(* pointer =='',''){

memmove(指针,指针+ 1,strlen(指针));

}

}

puts(" \ n / * BEGIN输出来自new.c * / \ n");

puts(foo);

puts(" \\\
/ * END output from new.c * /");

返回0;

}


/ * END new.c * /

-

pete



I think the smimplest way, is to read whole lines from the file
into strings, and then to process the strings in memory.

/* BEGIN output from new.c */

helloworldbyebyeworld

/* END output from new.c */

/* BEGIN new.c */

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

int main(void)
{
char foo[128] = "hello,world,bye,bye,world";
char *pointer;

for (pointer = foo; *pointer != ''\0''; ++pointer) {
if (*pointer == '','') {
memmove(pointer, pointer + 1, strlen(pointer));
}
}
puts("\n/* BEGIN output from new.c */\n");
puts(foo);
puts("\n/* END output from new.c */");
return 0;
}

/* END new.c */
--
pete


嗨皮特,

在我看来你误解了OP的问题:
Hi pete,
it seems to me that you misunderstood the OP''s question:
我正在解析一个CSV文件。
我想把每一行读成一个合理大小的字符数组,然后
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^从中提取字符串。
^^^^^^^^^^^^^^^^^^^^^^^^^

注意:OP正在逐行处理。 />
他想设置s1到s5。

[snip!代码<代码段>我觉得最简单的方法是将文件中的整行读入字符串,然后处理内存中的字符串。
I am parsing a CSV file.
I want to read every row into a char array of reasonable size and then ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^extract strings from it. ^^^^^^^^^^^^^^^^^^^^^^^^^
Note: The OP is doing things line by line.
He wants to set s1 through s5.
[snip! code <snippet> and questions to that]
I think the smimplest way, is to read whole lines from the file
into strings, and then to process the strings in memory.



如果我正确理解他/她,OP会做什么。


/ *来自new.c的BEGIN输出* /

helloworldbyebyeworld

/ *来自new.c的END输出* /

/ * BEGIN new.c * /

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

int main(void)
{char foo [128] =" hello,world,bye,bye ,world" ;;
char *指针;

for(pointer = foo; * pointer!=''\'''; ++指针){
if(*指针=='',''){
memmove(指针,指针+ 1,strlen(指针));
}
}
puts(" \ n / *来自new.c * / \ n")的BEGIN输出;
puts(foo);
puts(" \ n / * END输出来自new.c * /");
返回0;
}

/ * END new.c * /


我建议进行以下修改:

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


#define MAXNUMENTRIES 5

int main(无效)
{
char foo [128] =" hello,world,bye,bye,world" ;;
char *指针,* s [MAXNUMENTRIES + 1];

size_t i = 0;
s [i ++] = foo; for(pointer = foo; * pointer!=''\'''; ++ pointer){
if(* pointer =='',''){
* pointer =''\\ \\ 0'';

s [i ++] =指针+ 1; }
断言(i< = MAXNUMENTRIES);

s [i] = NULL; / *表示有效条目的结尾* / puts(" \ n / * BEGIN输出来自new.c * / \ n");
for(i = 0; s [i]!= NULL; i ++)

puts(s [i]); puts(" \ n / * END输出来自new.c * /");
返回0;
}



Which is what the OP does, if I understood him/her correctly.

/* BEGIN output from new.c */

helloworldbyebyeworld

/* END output from new.c */
/* BEGIN new.c */

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

int main(void)
{
char foo[128] = "hello,world,bye,bye,world";
char *pointer;

for (pointer = foo; *pointer != ''\0''; ++pointer) {
if (*pointer == '','') {
memmove(pointer, pointer + 1, strlen(pointer));
}
}
puts("\n/* BEGIN output from new.c */\n");
puts(foo);
puts("\n/* END output from new.c */");
return 0;
}

/* END new.c */
I would suggest the following modification:
#include <stdio.h>
#include <string.h> #include <assert.h>

#define MAXNUMENTRIES 5
int main(void)
{
char foo[128] = "hello,world,bye,bye,world"; char *pointer, *s[MAXNUMENTRIES+1];
size_t i=0; s[i++] = foo; for (pointer = foo; *pointer != ''\0''; ++pointer) {
if (*pointer == '','') { *pointer = ''\0'';
s[i++] = pointer+1; }
} assert(i<=MAXNUMENTRIES);
s[i] = NULL; /* Signify end of valid entries */ puts("\n/* BEGIN output from new.c */\n"); for (i=0; s[i] != NULL; i++)
puts(s[i]); puts("\n/* END output from new.c */");
return 0;
}




我但是没有测试它;只是想说清楚

怎么做:-)

干杯

Michael



I did not test it, though; just wanted to make clear
how to do it :-)
Cheers
Michael


这篇关于sscanf解析疑问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆