2013-08-22 53 views
1

我有我格式化这样的城市列表:C/C++读取和写入长字符串的文件

{town, ...}, 
{...}, 
... 

阅读并建立每个乡镇和创建town1,town2,工程.... 问题是当我输出它时,第一行工作{镇,...},但第二行崩溃。 任何想法为什么?

我有[地区] [城镇](excel表)。

因此,每个区域重复有多少个城镇。 每个文件每行有1个区域/城镇。

judete包含每个区域重复1次。

AB 
SD 
PC 
.... 

orase包含城镇列表。

town1 
town2 
.... 

orase指数包含每个镇

AB 
AB 
AB 
AB 
SD 
SD 
SD 
PC 
PC 
... 

我想这样{ “town1”, “town2”,...}每行输出的区域(第5行)包含属于同一行judete的地区的城镇(第5行)。

这里是我的代码:

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

char judet[100][100]; 
char orase[50][900000]; 
char oras[100], ceva[100]; 

void main() 
{ 

    int i=0, nr; 
    FILE *judete, *index, *ORASE, *output; 
    judete = fopen("judete.txt", "rt"); 
    index = fopen("orase-index.txt", "rt"); 
    ORASE = fopen("orase.txt", "rt"); 
    output = fopen("output.txt", "wt"); 

    while(!feof(judete)) 
    { 
     fgets(judet[i], 100, judete); 
     i++; 
    } 

    nr = i; 
    char tmp[100]; 
    int where=0; 

    for(i=0;i<nr;i++) 
     strcpy(orase[i],""); 

    while(!feof(index)) 
    { 
     fgets(tmp, 100, index); 
     for(i=0;i<nr;i++) 
     { 
      if(strstr(judet[i], tmp)) 
      { 
       fgets(oras, 100, ORASE); 
       strcat(ceva, "\""); 
       oras[strlen(oras)-1]='\0'; 
       strcat(ceva, oras); 
       strcat(ceva, "\", "); 
       strcat(orase[i], ceva); 
       break; 
      } 

     } 
    } 


    char out[900000]; 

    for(i=0;i<nr;i++) 
    { 
     strcpy(out, ""); 
     strcat(out, "{"); 
     strcat(out, orase[i]); //fails here 
     fprintf(output, "%s},\n", out); 
    } 

} 

结果我从运行代码得到的是:

未处理的异常在0x00D4F7A9(msvcr110d.dll)在orase-judete.exe:0000005:访问违规写入地址0x00A90000。

+0

它是如何崩溃的?如果通过'gdb'运行它,会发生什么? 另外,不要使用strcat/strcpy。使用'n'版本('strncpy'等) –

+0

你可以给一个judete.txt的小样本吗? –

+1

@OliverMatthews'strncpy()'不比'strcpy()'更好,它只是有一个不同的谬误。 – 2013-08-22 13:46:15

回答

4

不要清除orase阵列,东阳你的循环

for(i-0;i<nr;i++) 
    strcpy(orase[i],""); 

错误( ' - ' 而不是 '=')执行0次。

+0

orase我没有清理它,因为我没有在那条线上放任何东西,我只是用“”来初始化它以防万一。 –

+1

@MihaiBratulescu:仔细阅读这一行。我怀疑它是(甚至接近)唯一的问题,但他指出的是一个真正的问题。 –

+0

好吧,我以为你拼错 - 不是我反正相同的效果,它崩溃 –

3

我认为无论您是在编写C还是C++,您都需要下定决心。你已经用这两个标记了这个,但是代码看起来像是纯C的。虽然C++编译器会接受大多数C,但结果并不是大多数人认为的理想C++。

由于您已将其标记为C++,因此我将假设您实际上想要(或完全正确)C++代码。编写良好的C++代码将与您当前的C代码有足够的差异,从头开始可能比尝试逐行重写代码更容易。

然而,我看到这样做的直接问题是,你没有真正指定你想要的输出。目前,我假定您希望每行输出都是这样的:"{" <town> "," <town> "}"

如果是这样的话,我会首先注意到输出看起来完全不依赖于您的judete文件。 oraseorase-index似乎完全足够。为此,我们的代码可以是这个样子:

#include <iostream> 
#include <string> 
#include <iterator> 
#include <fstream> 
#include <vector> 

// a class that overloads `operator>>` to read a line at a time: 
class line { 
    std::string data; 
public: 
    friend std::istream &operator>>(std::istream &is, line &l) { 
     return std::getline(is, l.data); 
    } 
    operator std::string() const { return data; } 
}; 

int main() { 
    // open the input files: 
    std::ifstream town_input("orase.txt"); 
    std::ifstream region_input("orase-index.txt"); 

    // create istream_iterator's to read from the input files. Note 
    // that these iterate over `line`s, (i.e., objects of the type 
    // above, so they use its `operator>>` to read each data item). 
    // 
    std::istream_iterator<line> regions(region_input), 
           towns(town_input), 
           end; 

    // read in the lists of towns and regions: 
    std::vector<std::string> town_list {towns, end}; 
    std::vector<std::string> region_list {regions, end}; 

    // write out the file of town-name, region-name: 
    std::ofstream result("output.txt"); 
    for (int i=0; i<town_list.size(); i++) 
     result << "{" << town_list[i] << "," << region_list[i] << "}\n"; 
} 

野老,由于这是C++,您通常需要将源保存为something.cpp而不是something.c编译器要正确识别它。

编辑:根据您的评论已经给了新的要求,显然你想要的东西更接近这个:

#include <iostream> 
#include <string> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <map> 

// a class that overloads `operator>>` to read a line at a time: 
class line { 
    std::string data; 
public: 
    friend std::istream &operator>>(std::istream &is, line &l) { 
     return std::getline(is, l.data); 
    } 
    operator std::string() const { return data; } 
}; 

int main() { 
    // open the input files: 
    std::ifstream town_input("orase.txt"); 
    std::ifstream region_input("orase-index.txt"); 

    // create istream_iterator's to read from the input files. Note 
    // that these iterate over `line`s, (i.e., objects of the type 
    // above, so they use its `operator>>` to read each data item). 
    // 
    std::istream_iterator<line> regions(region_input), 
           towns(town_input), 
           end; 

    // read in the lists of towns and regions: 
    std::vector<std::string> town_list (towns, end); 
    std::vector<std::string> region_list (regions, end); 

    // consolidate towns per region: 
    std::map<std::string, std::vector<std::string> > consolidated; 
    for (int i = 0; i < town_list.size(); i++) 
     consolidated[region_list[i]].push_back(town_list[i]); 

    // write out towns by region 
    std::ofstream output("output.txt"); 
    for (auto pos = consolidated.begin(); pos != consolidated.end(); ++pos) { 
     std::cout << pos->first << ": "; 
     std::copy(pos->second.begin(), pos->second.end(), 
      std::ostream_iterator<std::string>(output, "\t")); 
     std::cout << "\n"; 
    }  
} 
+0

我有一个C++项目(只是因为),但你的代码包含错误,我不知道很多(如果有的话)C + +纠正它们,也关于judete文件我需要它,因为我希望每行(第5行)包含属于该行的城镇(第5行) –

+0

我将它标记为C++,因为我的C++编程人员也可以帮助我。 –

+3

@MihaiBratulescu:如果您在尝试编译上面的代码时遇到错误,那么很可能您的编译器太旧了。上面的代码用g ++和VC++的当前版本干净地编译。如果你要求C++程序员来帮助你,他们很有可能会像我一样做,并试图帮助你编写C++ ... –

1

注意ceva永远不会初始化。

而不是使用strcpy初始化字符串,我会建议使用静态初始化:

char ceva[100]="";