我有一个我正在格式化的城市列表:
{town, ...},
{...},
...
阅读并建立每个城镇并创建town1,town2,.... 问题是当我输出它时,第1行工作{town,...},但第二行崩溃。 知道为什么吗?
我有[地区] [城镇](excel表)。
所以每个地区都会重复多少个城镇。 每个文件每行有1个地区/城镇。
judete包含重复1次的每个区域。
AB
SD
PC
....
orase包含城镇列表。
town1
town2
....
orase-index包含每个城镇的区域
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);
}
}
运行代码得到的结果是:
orase-judete.exe中0x00D4F7A9(msvcr110d.dll)的未处理异常:0xC0000005:访问冲突写入位置0x00A90000。
答案 0 :(得分:4)
你没有清除orase数组,因为你的循环
for(i-0;i<nr;i++)
strcpy(orase[i],"");
错误(' - '而不是'=')执行0次。
答案 1 :(得分:3)
我认为无论你是在写C还是C ++,你都需要先决定。你用两者标记了这一点,但代码看起来像是纯粹的C.虽然C ++编译器会接受大多数C,但结果并不是大多数人认为理想的C ++。
由于您已将其标记为C ++,因此我假设您实际上想要(或可以使用)C ++代码。编写良好的C ++代码将与您当前的C代码完全不同,它可能比重新尝试逐行重写代码或类似的代码更容易重新开始。
然而,我所看到的直接问题是你没有真正指定你想要的输出。目前我假设您希望每行输出都是这样的:"{" <town> "," <town> "}"
。
如果是这种情况,我首先要注意输出似乎根本不依赖于您的judete
文件。 orase
和orase-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";
}
Noe,由于这是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";
}
}
答案 2 :(得分:1)
请注意ceva
永远不会被初始化。
我建议使用静态初始化,而不是使用strcpy
来初始化字符串:
char ceva[100]="";