来自 malloc() 的流中的随机感叹号但如果删除该行就会消失?我破坏了堆吗?
我不经常使用 C,所以请原谅我在编码风格方面可能犯的任何错误:P 我目前遇到一个错误,我有点困惑:当我包含行 tokenCopy = 时malloc(sizeof(fileSize));
,我在文件输出到 std 的过程中大约 1/4 处收到随机感叹号,但如果删除/注释该行,数据将按预期显示:
MAY +1.32 D1 1002
JUNE -1.57 D3 201
JULY -2.37 D4 478
AUGUST +5.03 D2 930
SEPTEMBER -3.00 D1 370
OCTOBER +7.69 D1 112
和实际的当线路就位时我得到的输出:
MAY +1.32 D1 1002
JUNE -1.57 D3 2!
以及相关代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/**
* Machine struct - three column
**/
/**
* Parses the input file, size is the size of name
**/
char parseInputFile(char *name, int size) {
FILE *fp;
if ((fp = fopen(name,"r")) == NULL) {
printf("Cannot open file %s\n", name);
return 1;
}
else {
int fileSize;
fileSize = 0;
char *fileContent;
char *processedFileContent;
//get file size
fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
//allocate
fileContent = malloc(sizeof(fileSize));
processedFileContent = malloc(sizeof(fileSize));
//read
char c;
int g;
g=0;
while((c = getc(fp)) != EOF) {
fileContent[g] = c;
g++;
}
//process
char delim[6] = " ";
char *tokenCopy;
tokenCopy = malloc(sizeof(fileSize));
strcpy(tokenCopy, fileContent);
char *tokens = strtok(tokenCopy, delim);
while (tokens) {
tokens = strtok(NULL, delim);
}
puts(fileContent);
//printf("File Size: %i \n",fileSize);
//puts(tokenCopy);
return *processedFileContent;
}
}
int main(int argc, char *argv[])
{
//char *input;
if (argc == 1)
puts("You must enter a filename");
else {
int size = sizeof(argv[1]);
parseInputFile(argv[1],size);
}
return 0;
}
任何人都可以提供有关我做错了什么的任何见解(或者我的代码本身是否导致问题)?
I don't work with C often so please excuse any mistakes I might be making in terms of coding style :P I'm currently getting an error that I'm a bit stumped on: when I include the line tokenCopy = malloc(sizeof(fileSize));
, I get random a random exclamation about 1/4th of the way through the output of a file to std but if the line is removed/commented, the data displays as expected:
MAY +1.32 D1 1002
JUNE -1.57 D3 201
JULY -2.37 D4 478
AUGUST +5.03 D2 930
SEPTEMBER -3.00 D1 370
OCTOBER +7.69 D1 112
and the actual output I get when the line is in place:
MAY +1.32 D1 1002
JUNE -1.57 D3 2!
and the relevant code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/**
* Machine struct - three column
**/
/**
* Parses the input file, size is the size of name
**/
char parseInputFile(char *name, int size) {
FILE *fp;
if ((fp = fopen(name,"r")) == NULL) {
printf("Cannot open file %s\n", name);
return 1;
}
else {
int fileSize;
fileSize = 0;
char *fileContent;
char *processedFileContent;
//get file size
fseek(fp, 0, SEEK_END);
fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
//allocate
fileContent = malloc(sizeof(fileSize));
processedFileContent = malloc(sizeof(fileSize));
//read
char c;
int g;
g=0;
while((c = getc(fp)) != EOF) {
fileContent[g] = c;
g++;
}
//process
char delim[6] = " ";
char *tokenCopy;
tokenCopy = malloc(sizeof(fileSize));
strcpy(tokenCopy, fileContent);
char *tokens = strtok(tokenCopy, delim);
while (tokens) {
tokens = strtok(NULL, delim);
}
puts(fileContent);
//printf("File Size: %i \n",fileSize);
//puts(tokenCopy);
return *processedFileContent;
}
}
int main(int argc, char *argv[])
{
//char *input;
if (argc == 1)
puts("You must enter a filename");
else {
int size = sizeof(argv[1]);
parseInputFile(argv[1],size);
}
return 0;
}
Could anyone offer any insight into what I'm doing wrong (or if my code is causing problems in itself)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将文件的大小放入
fileSize
中,然后仅分配存储int
的空间,这就是sizeof(FileSize)
将为您提供的空间。这两行
应该是(假设您将读取的文本视为字符串):
并且在读取文件内容后,您应该在末尾添加“\0”。
也就是说,我真的不明白您想通过使用 strtok() 来实现什么目的。如果您只需要分离每一行的三个组成部分,则在读取文件时可以轻松完成,因为您一次读取一个字符。
如果您详细说明您想要实现的目标,我们可能会提供其他建议。
在下面的评论后更新
您应该退一步并重新考虑您的问题,因为我怀疑您根本不需要存储任何字符串。第一个值是月份名称,可以存储为整数,第二个值是双精度(或浮点数),第三个值似乎为“Dx”,其中 x 不同于1 到 4,这也可以是整数。它似乎是一个传感器的名称,所以我怀疑它无论如何都可以用整数编码,因为它们的数量肯定是有限的。第四个显然是另一个整数。
通过对这些字段的含义进行疯狂猜测,您的结构将如下所示:
现在,您可以一次读取一个字符来获取值,或者读取一整行并从那里获取值。
每次使用一个字符不需要任何额外的空间,但会导致程序更长(充满“if”和“while”)。阅读该行会稍微容易一些,但需要您处理行的最大尺寸。
正确的函数结构将对您有很大帮助:
其中
measures
可以是一个链接列表或一个可调整大小的结构数组,并假设您一次只处理一个字符。在完成之前还有很多其他细节需要设置,我希望这能帮助您找到正确的方向。
You put the size of the file in
fileSize
but then allocate only the space to store anint
that is whatsizeof(FileSize)
will give you.These two lines
should be (assuming you will treat the text you'll read as a string):
and, after having read the file content, you should put a '\0' at the end.
That said, I really don't get what you are trying to achieve by using
strtok()
. If you only need to separate the three components of each line, you can do it much easily while you read the file since you read it one character at the time.If you elaborate a little bit more on what you're trying to achieve, we might have other advice.
UPDATE AFTER COMMENT BELOW
You should step back a second and reconsider your problem as I suspect you don't need to store any string at all. The first value is a month name, which can be stored as an integer, the second is a double (or float), the third seems 'Dx' with x varying from 1 to 4, again this could be an integer. It seems the name of a sensor, so I suspect it could be coded in an integer anyway as there will surely be a finite number of them. And the fourth is clearly another integer.
With a wild guess on what those fields mean, your struct would look like something like this:
Now, you can get the values as you go one char at the time, or read an entire line and get the values from there.
Going one char at the time will not require any additional space but will result in a longer program (full of 'if' and 'while'). Reading the line will be slightly easier but will require you to handle the maximum size of a line.
A proper structuring of functions will help you a lot:
Where
measures
can be a linked list or a resizable array of your structs and assuming you'll go one char at the time.There are quite many other details you should set before you're done, I hope this will help you find the right direction.
您的
delims
字符串不是以 null 结尾的。此外,分隔符是逐个字符匹配的,因此重复空格六次是没有用的,对
strtok
的调用也不会匹配连续六个空格。也许您需要类似strpbrk
的东西。Your
delims
string is not null-terminated.Also, the delimiters are matched character-by-character, so there is no use repeating the space six times, nor will your call to
strtok
match a run of six spaces. Perhaps you need something likestrpbrk
.