我的 C 代码在 Windows 上完美运行,但在 Ubuntu 上却不行

我的 C 代码在 Windows 上完美运行,但在 Ubuntu 上却不行

输入文件的示例行:

[email protected] Andee SMITH 1234
ADAM [email protected] Andeee 21654
Anderea [email protected] SAMMY 3524654
[email protected] Andi BROWN 1245
Andie [email protected] KNOWY 2485
Andra [email protected] BRUCE 52445
Andrea [email protected] 246574 DENNIS
2154 Andreana [email protected] CHASE
Andree 21524 SIERRRA [email protected]
Andrei 154 MONDY [email protected]
4564765 Andria MALLE [email protected]
78 Andriana [email protected] WALLS
579874 [email protected] Andriette MOUNT
52445 [email protected] Andromache FRASSER
5478645 [email protected] Andy MCFLY
//This program about scanning names,surnames ext. from disordered txt file and creating new ordered txt file.

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

typedef struct{

char  id[50];
char name[50];
char lname[50];
char mail[50];

}Person;

int main(){

    char str[250];
    int count=0;
    char c;
    char previous;
    int index =0;
    int i,m,l;
    int j,k=0;
    Person person[300];
    char str1[250];
    char in[1];
    char p;
    Person temp;


    FILE *file= fopen("hw4_disordered_people.txt","r");


    while(c!=EOF){  // how many of struct

        c= fgetc(file);

        if(c=='\n'){

        ++count;
        }
    }
    fclose(file);

    //person *person= (person*)malloc(count+1*sizeof(person));

    file = fopen( "hw4_disordered_people.txt" , "r");
    while(fgets(str1,sizeof(str1),file)){
        ++index;
        for (j = 0; str1[j] != '\n'; ++j)
        {
            if (str1[j] != ' ' && str1[j+1] != '\n')
            {
                str[k] = str1[j];
                k++;
            }
            else  if (k > 0 )
            {
                if (str1[j+1] == '\n')
                {
                    str[k] = str1[j];
                    k++;
                }
                str[k] = '\0';
                k=0;




                if(str[0] >= '0' && str[0] <='9')
                {
                    strcpy(person[index].id,str);
                    //printf("%s ",person[index].id);
                    strcpy(str,"");

                }
                else if (str[1] >= 'A' && str[1] <='Z')
                {

                    if(strlen(person[index].lname) > 0){
                        //printf(" %s ",str);
                        strcat(person[index].lname," ");
                        strcat(person[index].lname,str);
                        strcpy(str,"");
                    }
                    else{
                        strcpy(person[index].lname,str);
                        //printf("%s ",person[index].lname);
                        strcpy(str,"");

                    }

                }
                else if ((str[1] >= 'a' && str[1] <='z') && (str[0] >= 'A' && str[0] <='Z'))
                {

                    if(strlen(person[index].name) > 0){
                        //printf(" %s ",str);
                        strcat(person[index].name," ");
                        strcat(person[index].name,str);
                        strcpy(str,"");
                    }
                    else{
                        strcpy(person[index].name,str);
                        //printf("%s  ",person[index].name);
                        strcpy(str,"");
                    }

                }
                else
                {
                    strcpy(person[index].mail,str);
                    //printf("%s ",person[index].mail);
                    strcpy(str,"");
                }

            }

        }
    }
     FILE *fp;

          fp=fopen("OrderedList.txt","w");
          for(i=1;i<=count;++i){


          fprintf(fp,"%s %s %s %s\n",person[i].name,person[i].lname,person[i].mail,person[i].id);
         }
}

答案1

你的程序有很多错误,下面列举几个:

FILE *file= fopen("hw4_disordered_people.txt","r");


while(c!=EOF){  // how many of struct

在这里,您没有检查文件是否打开成功,而是开始使用未初始化的变量c,从技术上讲,该变量可以分配内存中的任何值。即使使用假定的值,0这也是错误的,因为这假设文件至少有 1 个字节大,这意味着该程序可能会在传递给它的空文件时做出奇怪的事情。

while(c!=EOF){  // how many of struct
    c = fgetc(file);

    if(c=='\n'){
      ++count;
    }
}

正确的写法应该更接近于:

while ((c = fgetc(file)) != EOF) {
  ++count;
}

还值得注意的是,该程序的这一部分可以用命令来替换wc -l,该命令计算文件中有多少行。

if (str1[j+1] == '\n')

无法保证这j+1是该数组的有效索引。

char str[250];

无法保证文件中的一行不会超过 248 个字符(包括换行符和空终止符)

Person person[300];

无法保证输入文件不超过 300 行。

str[k] = '\0';

k可能现在指向字符数组的边界之外,尽管执行此操作所需的输入是一个非常特殊的边缘情况。

strcpy(person[index].id,str);

index如果超出范围则缓冲区溢出(300)

for(i=1;i<=count;++i){

这可能试图访问数组边界之外的数据。你在循环早期增加并丢弃数组的索引 0 这一事实很奇怪,但从技术上讲并不是错误,但你愿意将其count + 1作为有效地址进行访问这一事实是一个错误,如果你使用malloc没有固定数组大小或处理具有 300 个输入的文件,这将导致分段错误/程序崩溃。

您应该用它编译您的代码gcc -Wall,您可能会自动收到很多这样的警告。

如果您的课程材料允许,您应该使用带有标准模板库(STL)的 C++,在这种情况下,整个程序将只有几行代码,这些代码具有强有力的保证,即它不会出现这里介绍的许多内存错误,因为它会使用std::stringstd::istream减少这个问题,同时std::unordered_map加快查找速度。

相关内容