我想从输入文件中读取卡并打印出它们的值。
但是,当我尝试打印字符时,它会打印出'0'
。
如果我打印出字符'A'
,那么通常应该打印出int值65
,因为我将字符'A'
存储为Int。
有人可以帮我吗?
谢谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 100
#define MAX_LENGTH 14
int main(){
char *lines = malloc(max*sizeof(char));
char **colour = malloc(max*sizeof(char));
int *value =malloc(max*sizeof(int));
FILE *fp;
fp = fopen("config2.txt", "r");
if(fp == NULL){
printf("Cannot open filelist.txt\n");
return 1;
}
int i= 0;
while (i < max && fgets(lines, MAX_LENGTH, fp) != NULL) {
colour[i] = malloc(MAX_LENGTH);
sscanf(lines, "%s %d", colour[i], &value[i]);
printf("%s\n", colour[i]);
printf("%d\n", value[i]);
i++;
}
return 0;
}
输入:
RED A
RED 2
RED 3
RED 4
RED 5
RED 6
RED 7
RED 8
RED 9
RED 10
RED J
RED Q
RED K
答案 0 :(得分:1)
您的主要问题是处理'A'
或整数作为值,这是由于以下误解:可以使用A
格式将sscanf
与"%d"
进行解析说明符,不能。为什么?当您尝试用'A'
解析"%d"
时,会发生匹配失败,则不会从输入缓冲区中提取其他字符,并且返回用于{ {1}}是失败之前成功进行转换的次数。
当您拥有不同类型的数据时,例如
sscanf
为了解析RED A
RED 2
或A
的值,它将需要两个不同的2
表达式,您可以通过检查轻松区分它们为sscanf
返回。您有条件地执行此操作,如果使用sscanf
的解析失败,则尝试使用"%s %d"
进行解析,并验证是否成功。
例如,说不用分配"%s %c"
(无论如何也不分配),只需声明一个结构数组即可保存从各行读取的malloc
和color
,例如
value
上面的...
#define MAXCOLR 14
#define MAXLINE 100
#define MAXCHR 1024 /* don't skimp on read buffer size */
typedef struct { /* simple struct to associate each color/value */
char color[MAXCOLR];
int value;
} colorval_t;
int main (int argc, char **argv) {
size_t ndx = 0; /* index */
char buf[MAXCHR]; /* read buffer */
colorval_t arr[MAXLINE] = {{ .color = "" }}; /* array of struct */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
...
while (ndx < MAXLINE && fgets (buf, MAXCHR, fp)) {
char c; /* temp char to use for parsing 2nd case */
if (sscanf (buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
ndx++;
else if (sscanf (buf, "%13s %c", arr[ndx].color, &c) == 2) {
arr[ndx].value = c;
ndx++;
}
}
循环是用于处理从每一行读取到while
中的信息解析的操作代码。第一个buf
调用尝试将解析解析为字符串和整数值。如果返回的不是sscanf
,则再次调用2
,以尝试将内容解析为字符串和字符。如果成功,则将字符值(例如,字符的ASCII值)分配给sscanf
,这在您的问题中似乎就是您想要的。
添加一些验证,然后为value
中包含的每个结构输出color
和value
,您可以执行以下操作。 (注意:该程序将文件名作为第一个参数读取,或者如果没有给出参数,则默认情况下从arr
读取。不要对文件名进行硬编码。要么将文件名作为参数传递或提示其输入)
stdin
(注意:使用 field-width 修饰符#include <stdio.h>
#define MAXCOLR 14
#define MAXLINE 100
#define MAXCHR 1024 /* don't skimp on read buffer size */
typedef struct {
char color[MAXCOLR];
int value;
} colorval_t;
int main (int argc, char **argv) {
size_t ndx = 0;
char buf[MAXCHR];
colorval_t arr[MAXLINE] = {{ .color = "" }};
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (ndx < MAXLINE && fgets (buf, MAXCHR, fp)) {
char c;
if (sscanf (buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
ndx++;
else if (sscanf (buf, "%13s %c", arr[ndx].color, &c) == 2) {
arr[ndx].value = c;
ndx++;
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (size_t i = 0; i < ndx; i++)
printf ("arr[%2zu] : %-14s %d\n", i, arr[i].color, arr[i].value);
return 0;
}
保护13
的字符数组边界)
使用/输出示例
将数据用作输入将导致以下结果:
color
仔细检查一下,如果还有其他问题,请告诉我。
答案 1 :(得分:0)
以下建议的代码:
sscanf()
的调用失败时,正确清理(关闭文件)。main()
使用有效的签名%s
上正确使用MAX CHARACTERS修饰符,以避免任何可能的缓冲区溢出和未定义的行为sscanf()
的调用之间的不匹配强烈建议您阅读有关atoi()
和strtol()
的信息,并修改对sscanf()
的调用,以期望有两个char序列并相应保存。 现在,建议的代码:
#include <stdio.h> // printf(), fprintf(), sscanf()
#include <stdlib.h> // exit(), EXIT_FAILURE
//#define MAX_LINES 100
#define MAX_LENGTH 14
int main( void )
{
char lines[ MAX_LENGTH +1];
char colour[ MAX_LENGTH ];
int value;
FILE *fp = fopen( "config2.txt", "r" );
if(fp == NULL)
{
perror( "fopen to read config2.txt failed" );
exit( EXIT_FAILURE );
}
while ( fgets( lines, MAX_LENGTH, fp ) )
{
if( sscanf(lines, "%100s %d", colour, &value) != 2 )
{
fprintf( stderr, "sscanf to extract two fields from input line failed\n" );
fclose( fp );
exit( EXIT_FAILURE );
}
printf( "colour: %s\n", colour );
printf( "value: %d\n", value );
}
fclose( fp );
return 0;
}
答案 2 :(得分:0)
您的代码几乎可以正常工作。主要问题是您不能使用格式说明符“%s%d”来不扫描“ RED A”之类的行,因为A不是整数。相反,您可以使用char对其进行扫描。
此外,您对malloc
的{{1}}有疑问。您需要colour
,因为您需要一个char指针数组。
因此,请尝试以下操作:
sizeof(char*)
输出:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 100
#define MAX_LENGTH 14
int main(){
char *filename = "config2.txt";
char *lines = malloc(max*sizeof(char));
char **colour = malloc(max*sizeof(char*)); // Use sizeof(char*)
char *value =malloc(max*sizeof(char)); // Use char instead of int
FILE *fp;
fp = fopen(filename, "r");
if(fp == NULL){
fprintf(stderr, "Cannot open %s : ", filename);
perror("");
exit(1);
}
int i= 0;
while (i < max && fgets(lines, MAX_LENGTH, fp) != NULL) {
colour[i] = malloc(MAX_LENGTH);
if (sscanf(lines, "%s %c", colour[i], &value[i]) != 2) // Use %c instead of %d and check return value
{
printf("Unexpected input file data\n");
exit(1);
}
printf("%s ", colour[i]);
printf("%c (%d)\n", value[i], value[i]); // Print value as both char and int
i++;
}
// Clean up
fclose (fp);
for (int j = 0; j<i; ++j) free(colour[j]);
free(colour);
free(value);
return 0;
}
还要注意,您应始终检查RED A (65)
RED 2 (50)
RED 3 (51)
RED 4 (52)
RED 5 (53)
RED 6 (54)
RED 7 (55)
RED 8 (56)
RED 9 (57)
RED 1 (49)
RED J (74)
RED Q (81)
RED K (75)
的返回值。示例:
malloc