这是我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main(int arge, char *argv[])
{
FILE *f1;
char ch,*fn="~/lyrics/";
strcat(fn,argv[1]);
strcat(fn,".txt");
if( (f1 = fopen(fn,"r"))==NULL )
{
printf("nWrong filenamen%s not found",argv[1]);
return;
}
while((ch=getw(f1))!=EOF)
{
printf("%c",ch);
}
}
我使用 gcc -g -o file file.c
编译了它,编译器没有给出任何错误消息。但是当我运行它时,我收到错误消息:
Segmentation fault (core dumped)
Bad permissions for mapped region at address 0x8048659 at 0x402C36B: strcat
(in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) by 0x80484D6: main (lyrics.c:9)
谁能帮我?
fn 中没有足够的空间。 通过对它进行strate,您可以覆盖其堆栈分配的末尾并进入堆栈..因此存在分段错误。
您可以尝试以下操作:
char fn[255];
strcpy( fn, "~/lyrics/" );
strcat( fn, argv[1] );
strcat( fn, ".txt" );
您只需要确保整个路径和文件名可以容纳 255 个字符。
或者,您可以这样做:
char* fn = NULL;
int argvLen = strlen( argv[1] );
fn = malloc( 9 + argvLen + 4 + 1 ); // Add 1 for null terminator.
strcpy( fn, "~/lyrics/" );
strcat( fn, argv[1] );
strcat( fn, ".txt" );
而且您肯定已经为字符串分配了足够的空间。 只是不要忘记在完成它时释放它!
char *fn = "~/lyrics/";
由于fn
可以指向只读内存中的字符串,因此应将fn
声明为指向const char
的指针。
const char *fn = "~/lyrics/";
然后你可以看到有一些错误。这是一个更好的解决方案:
char fn[MAX_SIZE] = "~/lyrics/";
这里的MAX_SIZE
应为"~/lyrics/"
的大小、argv[1]
的最大长度和".txt"
长度的总和。
此方法不可移植。
如果使用glibc
,您也可以调用asprintf()
它只是根据需要分配尽可能多的内存。
#include <stdio.h>
...
char * pFn = NULL;
if (-1 == asprintf(&pFn, "~/lyrics/%s.txt", argv+1);
{
perror("asprintf()");
}
else
{
... /* use pFn */
}
free(pFn);
...
更好的方法是创建一个这样的函数:
#include <string.h>
char* joinString(char* s1, char* s2) {
char s[sizeof(s1) + sizeof(s2) + 1];
strcat(s, s1);
strcat(s, s2);
return s;
}