c - strcpy 产生重复的存储项

标签 c string memory struct

在我的程序中,我使用 strcpy 将文件逐行存储到结构数组的相应字段中。当我在存储之前读取输入时,它是正确的,因此我必须使用不正确/不安全/错误的方法将数据从存储的输入移动到结构变量。这是代码。

#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */
#include "./book.h"
#ifndef fileget_C
#define fileget_C
#endif // fileget_C

 void readlib(Book* Library){
  /*char stock[4][125];*/
  FILE *bookfile=fopen("/home/ninja/Sockets/bookstock.txt","r+");


  size_t len=0;
  int num;
  ssize_t read;
  char *stringin;


  int n;
  for(n=0; n<4; n=n+1){
  getline(&stringin, &len, bookfile); 
  strcpy(Library[n].isbn,stringin);
  //printf("%s",Library[n].isbn);/*working print statement*/
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  strcpy(Library[n].Author,stringin);
  //printf("%s",Library[n].Author);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  strcpy(Library[n].title,stringin);
  //printf("%s",Library[n].title);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  num=atoi(stringin);
  Library[n].edition=num;
  //printf("%d\n",Library[n].edition);
  stringin=NULL;

  getline(&stringin, &len, bookfile);
  Library[n].year=atoi(stringin);
  stringin=NULL;
  //printf("%d\n",Library[n].year);

  getline(&stringin, &len, bookfile);
  strcpy(Library[n].publisher,stringin);
  stringin=NULL;
  //printf("%s",Library[n].publisher);

  getline(&stringin, &len, bookfile);
  Library[n].inventory=atoi(stringin);
  stringin=NULL;
  //printf("%d",Library[n].inventory);

  getline(&stringin, &len, bookfile);
  Library[n].available=atoi(stringin);
  //printf("%d\n",Library[n].available);

  }
  // printf("%s",Library[0].title);
  //printf("%s",Library[1].title);
  //printf("%s",Library[2].title);
  //printf("%s\n",Library[3].title);

  // printf("%s",Library[0].Author);
  //printf("%s",Library[1].Author);
  //printf("%s",Library[2].Author);
  //printf("%s",Library[3].Author);

  for(n=0; n<4; n=n+1){
    printf("%s",Library[n].isbn);
    //printf("%s",Library[n].Author);
    //printf("%s\n",Library[n].title);
    //printf("%d\n",Library[n].edition);
    //printf("%d\n",Library[n].year);
    //printf("%s\n",Library[n].publisher);


   // printf("%d\n",Library[n].inventory);
   // printf("%d\n",Library[n].available);

    }

}

这是输出

9780132126953
9780123745408
9780133354690
9780072467505
9780132126953Andrew Tanenbaum, David Wetherall
Computer Networks
9780123745408Michael Donahoo, Kenneth Calvert
9780133354690William Stallings
9780072467505Yale Patt, Sanjay Patel

当我复制字符串时,它似乎可能正在写入相邻的内存区域,因此一个字符串被附加到另一个字符串。这是附带的文本文件

9780132126953
Andrew Tanenbaum, David Wetherall
Computer Networks
5
2011
Prentice-Hall
5
2
9780123745408
Michael Donahoo, Kenneth Calvert
TCP/IP Sockets in C
2
2009
Morgan Kaufman
3
0
9780133354690
William Stallings
Cryptography and Network Security
6
2014
Prentice-Hall
3
3
9780072467505
Yale Patt, Sanjay Patel
Introduction to Computing System from bits & gates to C & beyond
2
2004
McGraw-Hill
1
0

这里是调用 fileget

  #include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */
#include "./DieWithError.c"
#define ECHOMAX 255     /* Longest string to echo */
#include "./fileget.c"
#include "./climsg.h"

void DieWithError(char *errorMessage);  /* External error handling function */

void main()
{
    Book Library[4];

    readlib(Library);
    int n;
    for(n=0; n<4; n=n+1){
        //printf("%s",Library[n].isbn);
       // printf("%s\n",Library[n].Author);
       // printf("%s\n",Library[n].title);
        //printf("%s\n",Library[n].publisher);
       // printf("%d\n",Library[n].year);
        //printf("%d\n",Library[n].edition);
        //printf("%d\n",Library[n].inventory);
       // printf("%d\n",Library[n].available);

    }

    /* book’s validated ISBN-13*/




    int sock;                        /* Socket */
    struct sockaddr_in echoServAddr; /* Local address */
    struct sockaddr_in echoClntAddr; /* Client address */
    unsigned int cliAddrLen;         /* Length of incoming message */
    ClientMessage echoBuffer;        /* Buffer for echo string */
    unsigned short echoServPort=9836;     /* Server port */
    int recvMsgSize;                 /* Size of received message */





    /* Create socket for sending/receiving datagrams */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
        DieWithError("socket() failed");

    /* Construct local address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out structure */
    echoServAddr.sin_family = AF_INET;                /* Internet address family */
    echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
    echoServAddr.sin_port = htons(echoServPort);      /* Local port */

    /* Bind to the local address */
    if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
        DieWithError("bind() failed");

    for (;;) /* Run forever */
    {
        /* Set the size of the in-out parameter */


        /* Block until receive message from a client */
        recvfrom(sock, &echoBuffer, sizeof(echoBuffer), 0,(struct sockaddr *) &echoClntAddr, &cliAddrLen);
        char *request;
        if( echoBuffer.requestType==0)
            request="QUERY \n";
        if (echoBuffer.requestType==1)
            request="BORROW \n";
        if (echoBuffer.requestType==2)
            request="RETURN \n";



        /*printf("%s", "message received \n");*/
        /* Send received datagram back to the client */
        //sendto(sock, &echoBuffer, recvMsgSize, 0,
               //(struct sockaddr *) &echoClntAddr, sizeof(echoClntAddr));

    }
    /* NOT REACHED */
}

这是我的书结构的标题

#ifndef BOOK_H
#define BOOK_H

typedef struct examp
{
    char isbn[13];
    char Author[34];
    char title[65];
    int  edition;
    int year;
    char publisher [14];
    int  inventory;
    int available;


} Book;


#endif // BOOK_

最佳答案

当您在 C 中定义局部变量时,它不会被初始化,它的值不确定。使用这样的变量(除了初始化它)将导致未定义的行为。这是当您第一次调用 getline 时发生的情况,其中变量 stringin 未初始化。

您还存在一些内存泄漏,因为 getline 函数为您分配了内存,而您没有释放

此外,您没有错误检查,例如检查文件是否成功打开或您实际上可以读取任何内容,或者检查文件是否提前结束。

关于c - strcpy 产生重复的存储项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35538541/

相关文章:

python - 如何将空格和逗号分隔的数字字符串转换为 int 列表?

python - 使用 Python 正则表达式搜索最外层的括号

c++ - 怎么知道哪段内存全为零

java - VisualVM 和 YourKit 报告同一对象的不同保留大小

c - 需要创建一个删除列表中最后一个学生信息的函数

c - 如何将光标运动信号连接到函数 (GTK)

c - C字符串操作中汉字的处理

memory - cpu 如何决定将哪些数据放入哪些内存(ram、缓存、寄存器)?

c - 在 C 中使用 getopt_long 将参数传递给函数

c - 检查变量范围的程序与另一个逐一检查值的程序的效率如何?