Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么scanf会忽略最后一个值?_C_String_Parsing_Csv_Scanf - Fatal编程技术网

为什么scanf会忽略最后一个值?

为什么scanf会忽略最后一个值?,c,string,parsing,csv,scanf,C,String,Parsing,Csv,Scanf,我想从命令行读取一行CSV。用户以age,HH:MM:SS,number的形式输入它 我写了以下内容: int age; char timestamp[8]; int number; scanf("%d,%8[^,],%d", &age, timestamp, &number; printf("%d, %s, %d", age, timestamp, number); 当我输入23,abcd,9时,它将打印23,abcd,9 当我输入23,abcdefghijklmno,9时

我想从命令行读取一行CSV。用户以
age,HH:MM:SS,number
的形式输入它

我写了以下内容:

int age;
char timestamp[8];
int number;

scanf("%d,%8[^,],%d", &age, timestamp, &number;
printf("%d, %s, %d", age, timestamp, number);
当我输入
23,abcd,9
时,它将打印
23,abcd,9

当我输入
23,abcdefghijklmno,9
时,它将打印
23,abcdefgh,0

如何修复此问题?

请查看。 宣布小尺寸。。
时间戳[8]

而是使用类似于
时间戳[16]
的东西。在这种情况下,名称长度可以最大为16


另外,
%8
最多消耗8个字符。这是另一个原因。

scanf()和UB中使用的弱格式

%8[^,]
(读取8个非
'的
char
,“
)将
“HH:MM:S”读入太小的空间。因此,如果未定义的将8
char
和空字符存储到
时间戳[8]
中的行为没有杀死代码,那么尝试读取第二个
S
并与
匹配将停止扫描。不检查返回值(一个大的no-no),进一步隐藏了
number
未写入的事实

char timestamp[8];
//     12345678
// age, HH:MM:SS, number
scanf("%d,%8[^,],%d", &age, timestamp, &number;`
反而

char buf[100];
fgets(buf, sizeof buf, stdin);

// 1 bigger for the null character
char timestamp[8+1];

//                  v-- add space              check result --v
if (sscanf(buf, "%d, %8[^,],%d", &age, timestamp, &number) == 3) {
  printf("%d, %s, %d", age, timestamp, number);
} else {
  puts("Input data scan failed");
}

scanf()
是邪恶的。节省时间,避免头痛。使用
fgets()


这则广告由“练习安全输入”委员会提供。

如果您不确定逗号之间的字符串长度,可以扫描整数和逗号。使用
%n
说明符捕获扫描的字符数。最多扫描8个字符的字符串。然后使用strpbrk查找下一个逗号,并扫描该逗号和最后的整数

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


int main()
{
    char *comma = NULL;
    char csv1[] = "23, abcdefghijklmnop, 9";
    char timestamp[9]= "";
    int age = 0;
    int number = 0;
    int used = 0;

    if ( ( sscanf ( csv1, "%d ,%n %8[^,]", &age, &used, timestamp)) == 2) {
        if ( ( comma = strpbrk ( csv1 + used, ","))) {
            if ( ( sscanf ( comma, ",%d", &number)) == 1) {
                printf ( "%d, %s, %d\n", age, timestamp, number);
            }
        }
    }
    return 0;
}
#包括
#包括
#包括
int main()
{
字符*逗号=空;
char csv1[]=“23,abcdefghijklmnop,9”;
字符时间戳[9]=“”;
int年龄=0;
整数=0;
int=0;
if((sscanf(csv1,“%d,%n%8[^,]”,&age,&used,timestamp))==2){
如果((逗号=strpbrk(csv1+使用,“,”)){
if((sscanf(逗号,,%d,&数字))==1){
printf(“%d,%s,%d\n”,年龄、时间戳、编号);
}
}
}
返回0;
}

您有一个可以装8升水(时间戳[8])的桶,正在倒入15升水(abcdefghijklmno)。为什么你对桶里只有8升感到惊讶?我假设%8只读取了前8升。有没有办法让它在8之后停止读取并跳到下一个字段?好吧,您告诉scanf需要8个字符,后跟一个逗号。但是在加载了这8个字符之后,您没有逗号,您有一个
i
,因此其余的扫描模式失败-->
字符时间戳[9]允许nul终止符。问题是,我不想增加最大长度;我只是想让它在读取8个字符后找到下一个整数。这可能是因为scanf吗?