2013-10-27 289 views
0

所以我应该创建完成某项功能: 目的:程序重新洗牌的文本文件洗牌阵列(赛格故障)

  • 的行文件读入到一个数组
  • 计数线和最大长度
  • 计算用于阵列最大宽度
  • 获取文件指针到开始
  • 预订存储器字符串
  • 的动态数组
  • 读取一行并存储在分配的存储器
  • 转动\ n为进\ 0
  • 打印线从阵列(试验)
  • 随机阵列从阵列(试验)
  • 打印线
  • 免存储器和关闭文件

(只给一些背景)

然而,当我去打印洗牌数组,我得到分段错误。偶尔,它会打印一个或两个字符串,但有时它只是说“Shuffled Array”,然后出现分段错误。有任何想法吗?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 

// Accepts: command line input 
// Returns: 0 if no error 

int main(int argc, char *argv[]){ 
    int x = 0, i, lineCount = 0, maxLen = 0; 
    char line[500], temp; 
    FILE *file = fopen(argv[1], "r"); 
// check if file exists 
    if (file == NULL){ 
     printf("Cannot open file\n"); 
     return 1; 
    } 
// Gets lines, max length of string  
    while (fgets(line, sizeof(line), file) != NULL){ 
     lineCount++; 
     if (strlen(line) > maxLen) 
      maxLen = strlen(line); 
    } 
    rewind(file); 
    char *lineArray[lineCount]; 
    while (fgets(line, sizeof(line), file) != NULL) { 
      lineArray[x] = malloc(strlen(line)); 
     if (lineArray[x] == NULL){ 
      printf("A memory error occurred.\n"); 
      return(1); 
     } 
      strcpy(lineArray[x], line); 
// change \n to \0 
     lineArray[x][strlen(lineArray[x])-1] = '\0'; 
     x++; 
    } 
    printf("File %s has %d lines with maximum length of %d characters\n", 
     argv[1], lineCount, maxLen); 
    printf("Original Array\n"); 
    for (x = 0; x < lineCount; x++) 
     printf("%2d %s\n", x, lineArray[x]); 
// Shuffle array 
    srand((unsigned int) time(NULL)); 
    for (x = lineCount - 1; x >= 0; x--){ 
     i = (int) rand() % lineCount; 
     temp = lineArray[x]; 
     lineArray[x] = lineArray[i]; 
     lineArray[i] = temp; 
    } 
    printf("\nShuffled Array\n"); 
    for (x = 0; x < lineCount; x++) 
     printf("%2d %s\n", x, lineArray[x]); 
// free allocated memory 
    for (x = 0; x < lineCount; x++) 
     free(lineArray[x]); 
    free(lineArray); 
    fclose(file); 
    return 0; 
} 
+1

会发生什么,如果你硬编码输入的字符串,而不是试图从文件中读取他们? – Beta

+0

可能重复[文件作为字符串输入到数组中的行](http://stackoverflow.com/questions/19619343/file-input-into-array-by-line-as-string) – Vorsprung

+2

你已经问过这个,去做你的功课 – Vorsprung

回答

1

在我的机器上运行cc的输出使得错误非常明显。

$ cc tmp.c -o tmp 
tmp.c:46:14: warning: incompatible pointer to integer conversion assigning to 
     'char' from 'char *'; dereference with * [-Wint-conversion] 
     temp = lineArray[x]; 
      ^~~~~~~~~~~~~ 
       * 
tmp.c:48:22: warning: incompatible integer to pointer conversion assigning to 
     'char *' from 'char'; take the address with & [-Wint-conversion] 
     lineArray[i] = temp; 
        ^~~~~ 
         & 
2 warnings generated. 

你需要修复你的变量,你打算使用一个char *你不能使用char

对不起,使其更明确:

char line[500], temp; 

应该是:

char line[500], *temp; 

如果你想澄清这是为什么,让我知道。

最后,它不是C风格(除非您正在编写嵌入式C)来在方法的顶部声明变量。尽可能将它们声明为接近使用点。它使您更容易找到您声明的内容。例如,temp可以在循环的正上方声明,在循环中使用它,甚至更好。

哦,还有:

$ cc --version 
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn) 
Target: x86_64-apple-darwin13.0.0 
Thread model: posix 
+0

哦,段错误的确切原因是,将指针('char *')转换为char将导致数据丢失,从而使指针完全无效;因为指针只是一个'int'。 – Nava2

+1

*指针只是一个int *,这是错误的,绝对不能保证'int'可以保存一个指针值。 – ouah

+0

指针是所有平台上的'unsigned int'。这个大小可能会有所不同,你是正确的我忘记了未签名的部分。但是,这是POSIX标准,但不幸的不是C标准。很难找到一个现代的编译器,但不支持这一点。 – Nava2

0

你在这里做什么?

free(lineArray); 

lineArray是一个数组,定义为这样:

char *lineArray[lineCount]; 

你不应该试图free()它,因为你首先没有malloc()它。

最重要的是,这样的:

char line[500], temp; 

应该是这样的:

char line[500], *temp; 

为你的编译器应该想告诉你。

可能还有其他问题,但由于您选择不提供输入文件或提供不需要的程序版本,因此没有人可以编译并运行它以查找。

编辑:使上述变化,改变lineArray[x] = malloc(strlen(line));lineArray[x] = malloc(strlen(line) + 1);作为建议的另一个答案,并使用合适的输入文件,我得到下面的输出:

[email protected]:~/src/c/scratch$ ./sta testfile 
File testfile has 4 lines with maximum length of 13 characters 
Original Array 
0 john doe 
1 jane fish 
2 donny brutus 
3 fishy mcgee 

Shuffled Array 
0 john doe 
1 jane fish 
2 fishy mcgee 
3 donny brutus 
[email protected]:~/src/c/scratch$ 

你真的需要学习使用编译器不过,更好。你应该像这样调用gcc:

gcc -o myprog myfile.c -std=c99 -pedantic -Wall -Wextra 

得到所有最有用的警告。

+0

我为此道歉。我们正在使用的文件只有最后一个,然后我的名字和其他同学在不同的行上。 – WorldDominator