C 访问字符数组时出现分段错误
给定一个数字列表和一个正整数k,我必须一次反转列表中的元素k项。如果元素的数量不是k的倍数,则最后的剩余项目应保持不变: 例如: 输入:1,2,3,4,5;二, 产量:2,1,4,3,5 我使用了一个非常简单的概念,在两端取两个指针a和b进行交换,并在整个循环中迭代它们 我遇到了一个分割错误。我该如何纠正它 我的代码:C 访问字符数组时出现分段错误,c,arrays,segmentation-fault,C,Arrays,Segmentation Fault,给定一个数字列表和一个正整数k,我必须一次反转列表中的元素k项。如果元素的数量不是k的倍数,则最后的剩余项目应保持不变: 例如: 输入:1,2,3,4,5;二, 产量:2,1,4,3,5 我使用了一个非常简单的概念,在两端取两个指针a和b进行交换,并在整个循环中迭代它们 我遇到了一个分割错误。我该如何纠正它 我的代码: #include<stdio.h> #include<stdlib.h> #include<string.h> void reverse(ch
#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;
}
#包括
#包括
#包括
无效反向(字符str[],int p)
{
int i,j,k,a,b;
int len=strlen(str);
printf(“%d\n”,len);
a=0;
b=p-1;
而(1)
{
i=a;j=b;
而(j>i)
{
k=str[i];
str[i]=str[j];
str[j]=k;
i++;
j--;
}
a=a+p;
b=b+p;
如果(b>=len)
打破
}
对于(i=0;i可能还有其他方法,但此代码有效。您在reverse()
中的算法做得很好。在reverse()
函数中,唯一的更改是设置代码格式和添加更完整的诊断打印。main()
函数被重写为使用fgets()
读取一行,然后解析该行。如果没有其他操作,这样做会更容易报告错误输入(例如,尽管代码在不包含分号的行上不能正确报告,并且代码假定k
项在同一时间始终是一位数字,并且它不坚持使用逗号分隔的一位数字,以及…)
样本输出
调试原件
如果您必须调试原始代码,那么我添加的reverse()
中的诊断打印将有帮助
code,您需要考虑在每个字符到达时回显,也许还需要打印str
数组。在那里您需要小心,因为您用零填充了它。您可以使用printf(“字符串:%.*s\n”,k,str);
将输出限制为str
的第一个k
字符使用-g编译并通过dubugger运行。您可能需要重新考虑而(1)
和break
语句。这不是很好的样式。文件有多大?在数组中读取了多少?如果在预期之前得到EOF会发生什么?fgetc()
返回一个int
,而不是char
。如果文件包含一行,您的EOF检测将遇到一个新行,并重新启动循环以查找新的数字和分号…但得到EOF。但它不会停止,因为您没有检查每个fgetc()
。memset(str,'0',100)
可能应该是memset(str,'\0',sizeof(str));
,其中更重要的更改是'0'
到'\0'
@tristopia:没错,EOF检测存在问题。实际问题取决于char
是有符号的还是无符号的。如果有符号,则有有效字符(通常是ÿ,y-umlaut,U+00FF,带分音符的拉丁文小写字母y,0xFF)会被误认为是EOF。如果char
是无符号的,则返回值将永远不会与EOF匹配。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void reverse(char str[], int p)
{
int i, j, k, a, b;
int len = strlen(str);
printf("Input: %d: %s (%d)\n", len, str, p);
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;
}
printf("Output: ");
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(1);
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("File can't be openend:\n");
exit(1);
}
char line[100];
while (fgets(line, sizeof(line), fp) != 0)
{
printf("Read: %s", line);
fflush(0);
char str[100];
int k = 0;
int i = 0;
char c;
while ((c = line[i++]) != '\0')
{
if (c == ';')
break;
else if (c == ',')
continue;
else
str[k++] = c;
}
str[k] = '\0';
printf("String: %s\n", str);
if (c == ';')
{
c = line[i];
int p = c - '0';
reverse(str, p);
}
}
fclose(fp);
return 0;
}
1,2,3,4,5;2
1,2,3,4,5,6,7;3
1,2,3,4,5,6,7,8,9;2
1,2,3,4,5,6,7,8,9;3
1,2,3,4,5,6,7,8,9;4
1,2,3,4,5,6,7,8,9;5
Read: 1,2,3,4,5;2
String: 12345
Input: 5: 12345 (2)
Output: 2, 1, 4, 3, 5
Read: 1,2,3,4,5,6,7;3
String: 1234567
Input: 7: 1234567 (3)
Output: 3, 2, 1, 6, 5, 4, 7
Read: 1,2,3,4,5,6,7,8,9;2
String: 123456789
Input: 9: 123456789 (2)
Output: 2, 1, 4, 3, 6, 5, 8, 7, 9
Read: 1,2,3,4,5,6,7,8,9;3
String: 123456789
Input: 9: 123456789 (3)
Output: 3, 2, 1, 6, 5, 4, 9, 8, 7
Read: 1,2,3,4,5,6,7,8,9;4
String: 123456789
Input: 9: 123456789 (4)
Output: 4, 3, 2, 1, 8, 7, 6, 5, 9
Read: 1,2,3,4,5,6,7,8,9;5
String: 123456789
Input: 9: 123456789 (5)
Output: 5, 4, 3, 2, 1, 6, 7, 8, 9