我正在尝试读取包含字符串“a3rm5t?7!z *& gzt9v”的文本文件,并将所有数字字符放入字符串中,以便稍后转换为整数。
我目前正在尝试通过在读取文件后在缓冲区上使用sscanf,然后使用sprintf来保存在名为str的字符串中使用%u找到的所有字符。
但是,每次运行程序时,在str上调用printf时返回的整数都不同。我做得对,我做错了什么?
当文本文件包含类似“23dog”的字符串并且返回23时,此代码有效,但当字符串类似于23dog2时则不行。
编辑:我现在意识到我应该将数字字符放在字符ARRAY而不是一个字符串中。
int main(int argc, const char **argv)
{
int in;
char buffer[128];
char *str;
FILE *input;
in = open(argv[1], O_RDONLY);
read(in, buffer, 128);
unsigned x;
sscanf(buffer, "%u", &x);
sprintf(str,"%u\n", x);
printf("%s\n",str);
close (in);
exit(0);
}
答案 0 :(得分:1)
如果您只想过滤掉输入中的任何非数字,则无需使用scanf
,sprintf
等。只需循环遍历缓冲区并复制数字字符。
以下程序仅适用于从标准输入读取的单行输入,并且只有在长度小于512个字符的情况下,它才会给出正确的想法。
#include <stdio.h>
#define BUFFER_SIZE 512
int
main()
{
char buffer[BUFFER_SIZE]; /* Here we read into. */
char digits[BUFFER_SIZE]; /* Here we insert the digits. */
char * pos;
size_t i = 0;
/* Read one line of input (max BUFFER_SIZE - 1 characters). */
if (!fgets(buffer, BUFFER_SIZE, stdin))
{
perror("fgets");
return 1;
}
/* Loop over the (NUL terminated) buffer. */
for (pos = buffer; *pos; ++pos)
{
if (*pos >= '0' && *pos <= '9')
{
/* It's a digit: copy it over. */
digits[i++] = *pos;
}
}
digits[i] = '\0'; /* NUL terminate the string. */
printf("%s\n", digits);
return 0;
}
答案 1 :(得分:0)
解决此类问题的一个好方法是将整行读入buffer
,然后将pointer
分配给buffer
。然后,您可以使用指针逐步读取每个字符的缓冲区并对其进行适当的操作。以下是此方法的一个示例。 getline
用于从文件中读取行(它具有为buffer
分配空间并返回读取的字符数的优点)。然后根据getline
返回的缓冲区大小为字符串分配空间。请记住,完成后,您负责释放由getline
分配的内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, const char **argv)
{
char *buffer = NULL; /* forces getline to allocate required space */
ssize_t read = 0; /* number of characters read by getline */
size_t n = 0; /* limit of characters to read, (0 no limit) */
char *str = NULL; /* string to hold digits read from file */
char *p = NULL; /* ptr to use with buffer (could use buffer) */
int idx = 0; /* index for adding digits to str */
int number = 0; /* int to hold number parsed from file */
FILE *input;
/* validate input */
if (argc < 2) { printf ("Error: insufficient input. Usage: %s filename\n", argv[0]); return 1; }
/* open and validate file */
input = fopen(argv[1], "r");
if (!input) { printf ("Error: failed to open file '%s\n", argv[1]); return 1; }
/* read line from file with getline */
if ((read = getline (&buffer, &n, input)) != -1)
{
str = malloc (sizeof (char) * read); /* allocate memory for str */
p = buffer; /* set pointer to buffer */
while (*p) /* read each char in buffer */
{
if (*p > 0x2f && *p < 0x3a) /* if char is digit 0-9 */
{
str[idx] = *p; /* copy to str at idx */
idx++; /* increment idx */
}
p++; /* increment pointer */
}
str[idx] = 0; /* null-terminate str */
number = atoi (str); /* convert str to int */
printf ("\n string : %s number : %d\n\n", buffer, number);
} else {
printf ("Error: nothing read from file '%s\n", argv[1]);
return 1;
}
if (input) fclose (input); /* close input file stream */
if (buffer) free (buffer); /* free memory allocated by getline */
if (str) free (str); /* free memory allocated to str */
return 0;
}
<强>数据文件:强>
$ cat dat/fwintstr.dat
a3rm5t?7!z*&gzt9v
<强>输出:强>
$ ./bin/prsint dat/fwintstr.dat
string : a3rm5t?7!z*&gzt9v
number : 3579