【发布时间】:2013-04-11 06:34:00
【问题描述】:
给定一个数字列表和一个正整数 k,我必须反转列表的元素,一次 k 项。如果元素个数不是k的倍数,那么最后剩下的项应该保持原样:
例如: 输入:1,2,3,4,5;2
输出:2,1,4,3,5
我使用了一个非常简单的概念,我在两端取两个指针 a&b 进行交换,并在整个循环中迭代它们。
我遇到了分段错误。应该怎么改?
我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void reverse(char str[],int p)
{
int i,j,k,a,b;
int len=strlen(str);
printf("%d\n",len);
a=0;
b=p-1;
while(1)
{
i=a;j=b;
while(j>i)
{
k=str[i];
str[i]=str[j];
str[j]=k;
i++;
j--;
}
a=a+p;
b=b+p;
if(b>=len)
break;
}
for(i=0;i<len-1;i++)
printf("%c,",str[i]);
if(i==len-1)
printf("%c",str[i]);
printf("\n");
}
int main(int argc,char* argv[])
{
if(argc!=2)
{
printf("Wrong number of arguments\n");
exit(0);
}
FILE *fp;
fp=fopen(argv[1],"r");
if(fp==NULL)
{
printf("File can't be openend:\n");
exit(0);
}
char c;
c=fgetc(fp);
char str[100];
memset(str,'0',100);
int k,i;
while(1)
{
k=0;
while(c!=';')
{
if(c!=',')
{
str[k]=c;
k++;
c=fgetc(fp);
}
else
c=fgetc(fp);
}
str[k]='\0';
c=fgetc(fp);
int p=c-'0';
reverse(str,p);
c=fgetc(fp);
if(c==EOF)
break;
else
c=fgetc(fp);
}
return 0;
}
谢谢!
【问题讨论】:
-
使用 -g 编译并通过调试器运行。
-
您可能需要重新考虑
while(1)和break语句。这不是很好的风格。 -
文件有多大?你读入了多少数组?如果您提前获得 EOF,会发生什么?
-
fgetc()返回int,而不是char。如果文件包含单行,您的 EOF 检测将遇到换行符,并重新启动循环以寻找新的数字和分号......但获得 EOF。但它不会停止,因为您不会检查每个fgetc()。memset(str, '0', 100)应该是memset(str, '\0', sizeof(str));,其中更重要的变化是'0'到'\0'。 -
@tristopia:你说得对,EOF 检测存在问题。实际问题取决于
char是有符号还是无符号。如果它已签名,则有一个有效字符(通常是 ÿ、y-元音变音、U+00FF、带分音符号的拉丁小写字母 Y、0xFF)将被误认为 EOF。如果char是无符号的,那么返回的值将永远不会匹配 EOF。
标签: c arrays segmentation-fault