gpt4 book ai didi

C 将数据作为字符串读取并将其转换为 float 并写回文件中

转载 作者:行者123 更新时间:2023-11-30 16:42:54 25 4
gpt4 key购买 nike

我想读取包含字符串中数字的数据集,例如:(在此示例中,每个数字都有 3 位数字:128、6、-3 和 224)

128  6 -3224

并将它们写入 float ,如下所示:

nbr[0] = 128;
nbr[1] = 6;
nbr[2] = -3;
nbr[3] = 224;

然后计算一些内容(例如乘以 2)并将其写入另一个相同类型的文件中:

256 12 -6448

最佳答案

使用 scanf() 或其相关函数很困难; 非常很难。

%c%[…](扫描集)和 %n 之外的所有转换说明符都会跳过前导空格。这使得很难对固定宽度应用数字转换。

下面的所有代码默认假设该行上的数字不超过 20 个 - 它不会检查边界以确保这一点(但操作代码肯定应该这样做 - 或者可以使用动态内存分配来为数字分配更多空间当需要时)。

虚假代码 - 看起来很简单,但失败了

/* SO 4564-1845 */
#include <stdio.h>
#include <string.h>

int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin) != 0)
{
int nbr[20];
int num = 0;
int n;
int val;
int off = 0;
while (sscanf(line + off, "%3d%n", &val, &n) == 1)
{
printf("Got: %d - [%s] %d\n", val, line + off, n);
off += n;
nbr[num++] = val;
}

for (int i = 0; i < num; i++)
printf("%3d", nbr[i]);
putchar('\n');
}
return 0;
}

输出示例

这个程序被称为rd31。请注意,这里也有调试输出:

$ rd31 < data
Got: 128 - [128 6 -3224
] 3
Got: 6 - [ 6 -3224
] 3
Got: -32 - [ -3224
] 4
Got: 24 - [24
] 2
128 6-32 24
$

%3d 格式会跳过 "-3" 中的前导空格,并采用 2242作为第三个角色。这不是你想要的。

工作代码 - 更复杂,但通过

此代码继续使用 sscanf(),每个数字调用它两次,这可能不是最佳的。

/* SO 4564-1845 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin) != 0)
{
line[strcspn(line, "\n")] = '\0';
int nbr[20];
int num = 0;
int n;
int val;
char data[4];
int off = 0;
while (sscanf(line + off, "%3c%n", data, &n) == 1)
{
data[n] = '\0';
if (sscanf(data, "%d", &val) != 1)
{
fprintf(stderr, "Oops! [%s]\n", data);
break;
}
printf("Got: [%s] - [%s] = %d (%d)\n", data, line + off, val, n);
off += n;
nbr[num++] = val;
}

for (int i = 0; i < num; i++)
printf("%3d", nbr[i]);
putchar('\n');
}
return 0;
}

这有不同的诊断输出。它将数据读入字符串,然后转换该字符串。使用 data[n] = '\0'; 将使读取内容的末尾变为空。

输出示例

这个程序被称为rd53

$ rd53 < data
Got: [128] - [128 6 -3224] = 128 (3)
Got: [ 6] - [ 6 -3224] = 6 (3)
Got: [ -3] - [ -3224] = -3 (3)
Got: [224] - [224] = 224 (3)
128 6 -3224
$

我相信这就是你想要的。

替代代码 - 每个值仅使用一次 sscanf()

此代码使用 memmove() 将数据从行复制到缓冲区中进行转换。

/* SO 4564-1845 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin) != 0)
{
line[strcspn(line, "\n")] = '\0';
int nbr[20];
int num = 0;
int val;
char data[4];
int off = 0;
int len = strlen(line);
while (off < len)
{
memmove(data, line + off, 3);
data[3] = '\0';
if (sscanf(data, "%d", &val) != 1)
{
fprintf(stderr, "Oops! [%s]\n", data);
break;
}
printf("Got: [%s] - [%s] = %d\n", data, line + off, val);
off += 3;
nbr[num++] = val;
}

for (int i = 0; i < num; i++)
printf("%3d", nbr[i]);
putchar('\n');
}
return 0;
}

您还可以使用 atoi()strtol() 将字符串转换为数字。最多转换 3 位数字不存在溢出问题。尽管如此,非数字数据仍会引起一些小问题;如果使用 strtol(),您可以更好地防范它们,但这样做需要非常小心。 (有关更多详细信息,请参阅 Correct usage of strtol()?。)

输出示例

这个程序被称为rd89

$ rd89 < data
Got: [128] - [128 6 -3224] = 128
Got: [ 6] - [ 6 -3224] = 6
Got: [ -3] - [ -3224] = -3
Got: [224] - [224] = 224
128 6 -3224
$

关于C 将数据作为字符串读取并将其转换为 float 并写回文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45641845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com