[英]How to read comma separated data set using scanf_s - C Programming
我现在没有可以共享的工作代码,但基本上我想要实现的是读取用户输入或从以下格式的文件中读取:
1,2
2,5
3,4
4,5
etc...
或者
1,3 4,5 6,7 8,6 ... 所以逗号分隔的一对实数,我需要将它们分配给一个数组或二维数组并计算它们的均值、中位数、众数等...
我尝试了scanf_s("%d,",&n)
东西,但到目前为止都没有解决。 我真的是 C 的新手并且来自 Java,所以一切都非常混乱。 如果有任何提示或只是一个例子,将不胜感激。 我知道你也可以使用 fgets、gets 或 sscanf,但我还没有学会这些。
这是另一个用户发送的代码:(但我不太明白,因为它给了我 src 可能是 0 错误)
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char *src = (char*)malloc(sizeof(char) * 500);
fgets(src, 500, stdin);
int arr[500];
int index = 0;
int n;
while ( sscanf ( src, "%d,%n", &arr[index], &n ) == 1 ) {
printf("%d\n", arr[index]);
index++;
src += n;
}
return 0;
}
用
scanf_s("%d,%d", &n1, &n2);
一次读取每行上的两个数字。 您不能将%d,
用于第二个数字,因为它后面没有逗号。
scanf()
返回已处理的输入数。 由于您一次读取两个数字,您应该检查它是否返回2
,而不是1
。
int n1, n2;
while (scanf("%d , %d", &n1, &n2) == 2 ) {
printf("first number = %d, second number = %d\n", n1, n2);
}
如果输入格式可能真的不同(你的问题不是很确定), strtod()
是你的主要武器。
char *P = MyLine, *NewP; //MyLine is the input line
double Val[2];
do {
Val[0]=strtod(P, &NewP); //It reads the first value and shifts the pointer.
if (NewP==P) return ERROR_EMPTY_STRING; //No values found! Sometimes maybe OK, if empty lines are allowed.
P=NewP;
while (*P == ' ') P++; //Omitting empty space between first value and comma.
if (*P!=',') return ERROR_WRONG_FORMAT; //Wrong input: no comma between the values!
Val[1]=strtod(P, &NewP); //It reads the second value and shifts the pointer.
if (NewP==P) return ERROR_WRONG_FORMAT; //No second value found! This is definitely not OK.
P=NewP;
while (*P == ' ') P++; //Omitting probable trailing spaces (we don't need it for strtod() because it does it by itself, but we need it for the endline check);
ProcessSomehow(Val); //Process the pair
} while (*P && *P != '\r' && *P != '\n' );
return LINE_ENDED_OK;
此代码将解析
1,2
3,4
5,6
也
1,2 3,4 5,6
7,8 9,10 11,12
甚至这个
2, 4 1 , 5 6 ,8
1,3 4, 4
1,4 6 ,4 6, 8 2,7 2, 12 4, 8
任何东西,只要它们是逗号分隔的对,并且每一对至少用一个空格分隔。 您还可以轻松修改它以允许1,2; 4, 3; 2, 3 7, 2
1,2; 4, 3; 2, 3 7, 2
1,2; 4, 3; 2, 3 7, 2
或任何其他额外的分隔符。
#define
错误代码根据您自己的喜好(或使用任何其他错误处理,如果您愿意)。
有(至少)两个主要的解决方案。 一是继续单数读,这样你真的不会太在意有没有逗号; 另一种是成对读取数字。
选项 A 涉及对格式字符串从"%d,%n"
到"%d %n"
的细微调整,以便您找出数字的结尾(更准确地说,不是空格的第一个字符出现在数字之后的位置) , 并在循环中单独跳过逗号:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char data[500];
char *src = data;
fgets(src, 500, stdin);
int arr[500];
int index = 0;
int n;
while (sscanf(src, "%d %n", &arr[index], &n) == 1)
{
printf("%d\n", arr[index++]);
src += n;
if (*src == ',')
{
putchar('=');
src++;
}
}
return 0;
}
putchar('=')
让我看到逗号何时被跳过; 它不会出现在“生产”代码中。
示例输出(BashHere 字符串表示法):
$ read41 <<< '1,2 3,4 5,6 7, 8 9,10, 11 , 12xyz'
1
=2
3
=4
5
=6
7
=8
9
=10
=11
=12
$
小心—— scanf()
格式中的尾随空白对于交互式输入来说是毁灭性的,但对sscanf()
无害的。 请注意,数据中10
后有一个杂散的逗号,但此版本的代码并不关心这一点。 它也不关心换行符成对出现的位置(或者如果它在while (fgets(data, sizeof(data), stdin) != 0) { char *src = data; … }
上迭代, while (fgets(data, sizeof(data), stdin) != 0) { char *src = data; … }
不会关心它)。
选项 B 涉及成对阅读数字。 由于您在循环中使用sscanf()
,因此您仍然需要%n
转换规范。 格式字符串中的第二个空格(逗号之后)不是绝对必要的( %d
也会跳过空格),但它是无害的和对称的。 这要求必须在同一行上的成对数字之间有一个逗号(但逗号周围允许有空格或没有空格),并且成对必须出现在同一行上。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char data[500];
int arr[500];
int index = 0;
while (fgets(data, sizeof(data), stdin) != 0)
{
int n;
char *src = data;
while (sscanf(src, "%d , %d %n", &arr[index + 0], &arr[index + 1], &n) == 2)
{
printf("(%d,%d)\n", arr[index + 0], arr[index + 1]);
src += n;
index += 2;
}
}
return 0;
}
示例输出(也使用 Bash ANSI-C Quoting ):
$ read43 <<< $'1,2 3,4 5,6 7,8\n9,10 11 , 12xyz'
(1,2)
(3,4)
(5,6)
(7,8)
(9,10)
(11,12)
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.