c - fgets() 从一行中读取并存储一个字符两次
问题描述
所以我有一个文件data.txt
,其中写入了随机整数,例如"17 12 5 4 16"
.
所以,我曾经fgets()
读取这行整数并将其存储在char str []
. 正如预期的那样str [0] == 17
,但是str [1] == 7
,依此类推……整数每 2 位存储在数组中的一个元素中,但第二位也存储在后面的元素中。
示例: str [3] = 12
, str [4] = 2
, str[5] = ' '
.
可以做些什么来解决这个问题?
这是我非常典型的代码:
FILE* fp = fopen ("data.txt", "r");
int i = 0, j = 0;
int size = fileSize(fp) + 1; // Enumerate the char numbers in file
char str [size];
rewind (fp);
fgets (str, size, fp);
这是我的整个代码
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct RATIONAL
{
int top;
int bottom;
} RATIONAL;
void printArray (int arr [], int count)
{
for (int i = 0; i < count; ++i)
{
printf ("%d\n", arr[i]);
}
}
int fileSize (FILE* fp)
{
char c;
int i = 0;
while ((c = getc (fp)) != EOF)
{
i++;
}
return (i);
}
int main ()
{
RATIONAL ratArray [23]; //array to hold rational numbers
int intArray [45]; //array to hold integer values
FILE* fp = fopen ("data.txt", "r");
int i = 0, j = 0;
int size = fileSize(fp) + 1; // Enumerate the char numbers in file
char str [size];
rewind (fp);
fgets (str, size, fp);
//Convert string to array of ints
while (i < size -1)
{
if (isdigit (str [i]))
{
intArray[j++] = atoi(&str[i]);
i++;
}
else
i++;
}
printArray (intArray, intArray[0]);
输入:data.txt
解决方案
你所经历的一切都是意料之中的。关键的误解是您希望arr[N]
保存第 (N+1)个整数,因为它是一个整数数组……但事实并非如此。它是一个字符数组。
如果将整数存储在char
数组中,则每个数字都将占据一个数组位置。所以arr[0]
将包含第一个数字的最高有效位和arr[a]
最低有效位。
因此,在您的示例中,字符串"17 12 5 4 16"
将以这种方式存储:
--------------------------------------------------------------------------------------------
| 0x31 | 0x37 | 0x20 | 0x31 | 0x32 | 0x20 | 0x35 | 0x20 | 0x34 | 0x20 | 0x31 | 0x36 | 0x00 |
--------------------------------------------------------------------------------------------
| '1' | '7' | ' ' | '1' | '2' | ' ' | '5' | ' ' | '4' | ' ' | '1' | '7' | '\0' |
--------------------------------------------------------------------------------------------
所有数字都在同一个数组中,并用空格分隔。字符串由字符串终止符关闭'\0'
。
有趣的是,如果你打印整个字符串,printf("%s\n", arr)
你会得到
17 12 5 4 16
但是如果你尝试打印传递第二个字符的地址,printf("%s\n", &arr[1])
你会得到
7 12 5 4 16
等等。这意味着C 不知道(还不知道)您的意图是存储 5 个整数。在找到字符串终止符之前,字符串是一个(空格不会终止字符串),所以从第二个数字开始只会让 C 打印除第一个数字之外的所有字符串。
由于您有一个以众所周知的方式格式化的字符串并且您想要一个整数数组,因此您必须对其进行解析以获取整数:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char arr[] = "7 12 5 4 16";
int main()
{
char * token = strtok(arr, " ");
while(token != NULL)
{
printf("Next int: %d %s\n", atoi(token)); // Here you can assign the value to your array
token = strtok(NULL, " ");
}
return 0;
}
在我的演示示例中,输入字符串是一个全局数组,而不是像在您的场景中那样从文件中读取的内容,我使用了strtok()(strtok_r
可以在需要重入函数的情况下使用)并且我得到了整数使用简单atoi()
(只是因为输入格式是_under control - 我建议使用strtol()
它来更好地控制输入)。
推荐阅读
- java - 如何在 Springboot 中创建一对多关系
- matlab - 使用周期样条绘制参数样条曲线
- http - 服务器是否可以指定客户端使用 GET 或 POST 或其他方法请求重定向的 url?
- hadoop - 洗牌和排序,节点比对少
- python - 在遇到 AttributeError 的 keras 模型中计算 pearson 系数:“NoneType”对象没有属性“_inbound_nodes”
- javascript - 如何找到导致非自愿路由的代码位?(在旧网站中)
- spotfire - 在 Spotfire 中滚动过去 3 个月的平均列
- java - Java G1GC 从不收集 Old Gen
- python - 递归调用后递归循环不返回位置
- php - laravel 我需要向数据库中的表添加值