Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从键盘获取字符(内存分配)_C - Fatal编程技术网

C 从键盘获取字符(内存分配)

C 从键盘获取字符(内存分配),c,C,我想写一个程序,删除字符串中的任何单词(用户可以键入这个单词)。程序运行正常,但valgirnd给了我一些错误消息: ==3009== Command: ./remove3 infile ==3009== Type word that you want to remove from the file: go ==3009== Invalid write of size 1 ==3009== at 0x4009CD: main (remove3.c:74) ==3009== Addres

我想写一个程序,删除字符串中的任何单词(用户可以键入这个单词)。程序运行正常,但valgirnd给了我一些错误消息:

==3009== Command: ./remove3 infile
==3009== 
Type word that you want to remove from the file:
go
==3009== Invalid write of size 1
==3009==    at 0x4009CD: main (remove3.c:74)
==3009==  Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd
==3009==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3009==    by 0x400947: main (remove3.c:45)
==3009== 
==3009== Invalid read of size 1
==3009==    at 0x400AE6: DELTEword (remove3.c:115)
==3009==    by 0x400A39: main (remove3.c:90)
==3009==  Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd
==3009==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3009==    by 0x400947: main (remove3.c:45)
==3009== 
==3009== Invalid read of size 1
==3009==    at 0x400B16: DELTEword (remove3.c:118)
==3009==    by 0x400A39: main (remove3.c:90)
==3009==  Address 0x51f1041 is 0 bytes after a block of size 1 alloc'd
==3009==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3009==    by 0x400947: main (remove3.c:45)
==3009== 
That  Katharina and Petruchio should be married,
And yet we hear not of our son-in-law.
What will  be said? what mockery will it be,
To what bridegroom when the priest attends 
To speak the  ceremonial rites of marriage!
What says Lucentio to this shame of ours?
 ==3009== 
==3009== HEAP SUMMARY:
==3009==     in use at exit: 1 bytes in 1 blocks
==3009==   total heap usage: 50 allocs, 49 frees, 1,181 bytes allocated
==3009== 
==3009== LEAK SUMMARY:
==3009==    definitely lost: 1 bytes in 1 blocks
==3009==    indirectly lost: 0 bytes in 0 blocks
==3009==      possibly lost: 0 bytes in 0 blocks
==3009==    still reachable: 0 bytes in 0 blocks
==3009==         suppressed: 0 bytes in 0 blocks
==3009== Rerun with --leak-check=full to see details of leaked memory
==3009== 
==3009== For counts of detected and suppressed errors, rerun with: -v
==3009== ERROR SUMMARY: 95 errors from 3 contexts (suppressed: 2 from 2)
我还想问一下主体。我不完全确定我从键盘上获取字符的方式是否正确,例如:当我键入“go”时,一切正常,但“To”一词无法删除,为什么

这是我的密码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define CHUNK 12

char *getWord(FILE *infile);
int DELTEword(char *word, char *KEYword);

char *getWord(FILE *infile)
{
    int length, cursor = 0, c;
    char *word, *word2;

    word = (char*)malloc(sizeof(char)*CHUNK);
    if(word == NULL) return NULL;

    length = CHUNK;

        while((c = getc(infile)) != ' ' && !feof(infile))
        {
            word[cursor] = c;
            cursor++;

            if(cursor >= length)
            {
                length += CHUNK;
                word2 = (char*)realloc(word, length*sizeof(char));
                if(word2 == NULL)
                {
                    free(word);
                    return NULL;
                }
                else word = word2;
            }
        }

    word[cursor] = '\0';
    return word;
}

int main(int argc, char *argv[])
{
    char *word, c, *keyWord = (char*)malloc(sizeof(char));
    FILE *infile;
    int length;
    int size = 20;

    if(argc != 2)
    {
        printf("\nMissing arguments.\n");
        abort();
    }

    if(keyWord == NULL) return 0;

    printf("Type word that you want to remove from the file:\n");

    length = 0;

    while(1)
    {
        if(length == size)
        {
            keyWord = (char*)realloc(keyWord, size + 10);
            size += 10;
        }

        c = getchar();

        if(c == '\n') break;

        keyWord[length] = c;
        length++;
    }

    infile = fopen(argv[1], "r");
    if(infile != NULL)
    {
        while(!feof(infile))
        {
            word = getWord(infile);
            if(word == NULL)
            {
                free(word);
                break;
            }

            if(DELTEword(word, keyWord) == 1)
            {
                printf(word, infile);
                printf(" ");
                free(word);
            }
        }
    }
    else
    {
        printf("It is impossible to open the infile\n");
        abort();
    }

    fclose(infile);
    return 0;
}

int DELTEword(char *word, char *KEYword)
{
    int i, k = 0, l = 0, length;
    char *ptr;

    if(word != NULL)
    {
        length = strlen(KEYword);
        for(i = 0; word[i] != '\0'; i++)
        {
            if(word[i] == KEYword[k])
            {
                l++;
                k++;
            }
            else break;

            if(l == length)
            {
                ptr = &word[i];
                memmove((ptr - length) + 1, ptr + 1, strlen((ptr - length) + 1));
                l = 0;
                k = 0;
            }
        }
        return 1;
    }
    else return 0;
 }
#包括
#包括
#包括
#包括
#定义区块12
char*getWord(文件*infle);
int DELTEword(字符*单词,字符*关键字);
char*getWord(文件*infle)
{
int长度,游标=0,c;
字符*word,*word2;
word=(char*)malloc(sizeof(char)*CHUNK);
if(word==NULL)返回NULL;
长度=块;
而((c=getc(infle))!=''&!feof(infle))
{
字[光标]=c;
游标++;
如果(光标>=长度)
{
长度+=块;
word2=(char*)realloc(word,length*sizeof(char));
if(word2==NULL)
{
免费(字);
返回NULL;
}
else单词=单词2;
}
}
字[光标]='\0';
返回词;
}
int main(int argc,char*argv[])
{
char*word,c,*关键字=(char*)malloc(sizeof(char));
文件*填充;
整数长度;
int size=20;
如果(argc!=2)
{
printf(“\n缺少参数。\n”);
中止();
}
如果(关键字==NULL)返回0;
printf(“键入要从文件中删除的单词:\n”);
长度=0;
而(1)
{
如果(长度==大小)
{
关键字=(char*)realloc(关键字,大小+10);
尺寸+=10;
}
c=getchar();
如果(c=='\n')中断;
关键词[长度]=c;
长度++;
}
infle=fopen(argv[1],“r”);
if(infle!=NULL)
{
而(!feof(infle))
{
word=getWord(infle);
if(word==NULL)
{
免费(字);
打破
}
if(DELTEword(word,关键字)==1)
{
printf(word,infle);
printf(“”);
免费(字);
}
}
}
其他的
{
printf(“无法打开填充文件”);
中止();
}
fclose(infle);
返回0;
}
int DELTEword(字符*单词,字符*关键字)
{
int i,k=0,l=0,长度;
char*ptr;
if(word!=NULL)
{
长度=strlen(关键字);
for(i=0;单词[i]!='\0';i++)
{
if(单词[i]==关键字[k])
{
l++;
k++;
}
否则就断了;
如果(l==长度)
{
ptr=&word[i];
memmove((ptr-长度)+1,ptr+1,strlen((ptr-长度)+1));
l=0;
k=0;
}
}
返回1;
}
否则返回0;
}

感谢您的帮助。

参考Valgrind记录的无效写入/读取:

分配1个字节并将
大小设置为
20

char *word, c, *keyWord = (char*)malloc(sizeof(char));
...
int size = 20;
这应该以某种方式联系起来,例如:

int size = 20;
char *word, c, *keyWord = malloc(size * sizeof(*keyWord));

此外,您似乎没有为“字符串”的
0
-终止符分配空间。在C语言中,“字符串”是一种字符数组,其最后一个有效字符由下面的
NUL
字符表示

因此,您始终需要再分配一个,然后“字符串”能够容纳的最大字符数



顺便说一句:在C语言中,不需要强制转换malloc/calloc/realloc,也不建议使用:

引用Valgrind记录的无效写入/读取:

分配1个字节并将
大小设置为
20

char *word, c, *keyWord = (char*)malloc(sizeof(char));
...
int size = 20;
这应该以某种方式联系起来,例如:

int size = 20;
char *word, c, *keyWord = malloc(size * sizeof(*keyWord));

此外,您似乎没有为“字符串”的
0
-终止符分配空间。在C语言中,“字符串”是一种字符数组,其最后一个有效字符由下面的
NUL
字符表示

因此,您始终需要再分配一个,然后“字符串”能够容纳的最大字符数


顺便说一句:在C语言中,不需要强制转换malloc/calloc/realloc,也不建议: