我有一个我想尝试的基本算法,为此我有一个txt
文件,其中包含许多输入。为此,我使用编译器stdin
中的命令将input.txt
重定向到我的./prog < input.txt
。这是提到的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void ExA(int n, int VALOR, int *sequencia){
int i,j,z,soma;
printf("%d - %d - %d\n",sequencia[0],sequencia[1],sequencia[2]);
for(i=1; i<=n; i++){
for(j=i; j<=n; j++){
soma = 0;
for(z=i; z<=j; z++){
soma = soma + sequencia[j];
}
if(soma == VALOR){
printf("SUBSEQUENCIA NA POSICAO %d\n", i);
return;
}
}
}
printf("SUBSEQUENCIA NAO ENCONTRADA\n");
}
int main(void){
int n, i, VALOR;
int *sequencia = malloc(sizeof(int));
char *buffer = malloc(sizeof(int) * 4);
while(read(0, buffer ,sizeof(buffer))){
sscanf(buffer,"%d %d",&n ,&VALOR);
if(n == 0 && VALOR == 0){
return 0;
}
else{
for(i = 0; i<n; i++){
read(0, buffer ,sizeof(buffer));
sscanf(buffer,"%d",&sequencia[i]);
}
}
ExA(n,VALOR,sequencia);
}
return 0;
}
主函数负责从输入文件中读取并将值发送到算法ExA
。在我的input.txt
文件中,我从以下内容开始:
3 5
1
3
4
4 5
1
5
4
2
但是,当我打印出我应该存储数字的数组(在ExA
函数的开头)时,它打印出1 - 4 - 5
而不是想要的1 - 3 - 4
答案 0 :(得分:2)
请注意read()
不处理字符串 - 它不会为它读取的内容添加空终止符。因此,您传递sscanf()
一个字节数组而不是保证(空终止)字符串。
此外,read()
并不关注换行符。它一次读取4或8个字节(除非你这些天在一台非常不寻常的机器上),因为sizeof(buffer)
是指针的大小。假设您有一台64位计算机,第一个read()
处理前3行(3 5
,1
,3
- 它们恰好是8个字节长);第二个read()
获得后三行(4
,4 5
,1
)并进行适当报告。
您应该从read()
捕获并测试返回值。你应该打印它得到的东西。 (部分修复的代码 - 要使程序完全正常工作还需要做更多的工作。)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void ExA(int n, int VALOR, int *sequencia)
{
int i, j, z, soma;
printf("%d - %d - %d\n", sequencia[0], sequencia[1], sequencia[2]);
for (i = 1; i <= n; i++)
{
for (j = i; j <= n; j++)
{
soma = 0;
for (z = i; z <= j; z++)
{
soma = soma + sequencia[j];
}
if (soma == VALOR)
{
printf("SUBSEQUENCIA NA POSICAO %d\n", i);
return;
}
}
}
printf("SUBSEQUENCIA NAO ENCONTRADA\n");
}
int main(void)
{
int n, i, VALOR;
int *sequencia = malloc(sizeof(int));
char *buffer = malloc(sizeof(int) * 4);
while (read(0, buffer, sizeof(buffer)))
{
sscanf(buffer, "%d %d", &n, &VALOR);
if (n == 0 && VALOR == 0)
{
return 0;
}
else
{
for (i = 0; i < n; i++)
{
int nbytes = read(0, buffer, sizeof(buffer));
printf("Read [%.*s]\n", nbytes, buffer);
buffer[nbytes] = '\0';
sscanf(buffer, "%d", &sequencia[i]);
}
}
ExA(n, VALOR, sequencia);
}
return 0;
}
鉴于问题中显示的输入,我得到输出:
Read [4
4 5
1
]
Read [5
4
2
]
[]
4 - 5 - 5
SUBSEQUENCIA NA POSICAO 1
这项工作清理了代码 - 并解释了一些你得到的奇怪结果。它没有充分利用分配的空间(大于sizeof(buffer)
,因此buffer[nbytes] = '\0';
赋值在数组的范围内。它在sscanf()
中重复读取相同的值调用,因为你没有告诉它从字符串中的不同位置读取。如果你需要使用scanf()
从缓冲区读取多个值,请阅读关于How to use sscanf()
in a loop?的答案
您应该考虑使用fgets()
或POSIX getline()
来读取行。如果您确定数据是干净的,您甚至可以直接使用scanf()
,但通常最好先读取行,然后使用sscanf()
解析它们。
如果练习要求您使用read()
系统调用进行阅读,那么您将需要制定一个方案,在该方案中,您读取一个充满数据的缓冲区并以块的形式发送内容。