0

In the below code, the file test.txt has the following data :

192.168.1.1-90    
192.168.2.2-80    

The output of this is not as expected. I expect the output to be

192.168.1.1    
90     
192.168.2.2   
80

The current output is

192.168.2.2    
80     
192.168.2.2     
80

I know that the pointer of str is pointing to the same address in the second iteration as well.

Im just not able to the problem. Any help would be appreciated.

#include <string.h> 
#include <stdio.h>
#include <stdlib.h>
int main() {
  FILE * fp;
  char * result[10][4];
  int i = 0;
  const char s[2] = "-";
  char temp[50];
  char * value, str[128], * string, t[20], x[29] = "192.168.2.2";
  fp = fopen("test.txt", "r");
  if (fp == NULL)
    printf("File doesn't exist\n");
  else {
    while (!feof(fp)) {

      if (fgets(str, sizeof(str), fp)) {

        /* get the first value */
        value = strtok(str, s);

        result[i][0] = value;
        printf("IP : %s\n", result[i][0]); //to be removed after testing


        /* get second value */
        value = strtok(NULL, s);

        result[i][1] = value;
        printf("PORT : %s\n", result[i][1]); //to be removed after testing
        i++;
      }
    }
    for (int k = 0; k < 2; k++) {
      for (int j = 0; j < 2; j++) {
        printf("\n%s\n", result[k][j]);
      }
    }

  }
  return (0);
}
Elfayer
  • 4,411
  • 9
  • 46
  • 76
vatsal511
  • 3
  • 5
  • Do you need `char *result[10][4];`? Why not just have an array of strings instead, like `char *result[4]`? – RoadRunner Nov 04 '16 at 13:17
  • @RoadRunner, its like i want to store the IP and port number separately. – vatsal511 Nov 04 '16 at 13:18
  • So, i'm trying to make a row and column scenario, where column one is IP and column 2 is port number – vatsal511 Nov 04 '16 at 13:19
  • 3
    Related: [Why is `while (!feof(file))` always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – John Bollinger Nov 04 '16 at 13:20
  • Oh okay @vatsal511. Yeah then that's fine. I wasn't quite sure what you're aim was. – RoadRunner Nov 04 '16 at 13:21
  • So @RoadRunner any help.? – vatsal511 Nov 04 '16 at 13:22
  • If you want two columns, then why do declare `result` to have four? – John Bollinger Nov 04 '16 at 13:28
  • The code evidently assumes that the input file will never have more than ten lines. It's ok for it to be unable to handle more, but in that case it should *detect* the case that there are actually more, and fall back to some reasonable, *defined* behavior, such as ignoring the excess or erroring out. Accustom yourself to writing safe code. – John Bollinger Nov 04 '16 at 13:31
  • @Quentin, `while(!feof(file))` is *always* semantically wrong, even if, as in this case, it happens not to break the program. In cases such as this, it is wrong at least because it is wasteful. In this particular case, the `while` should be removed, and the `if` statement inside converted into a `while`. – John Bollinger Nov 04 '16 at 13:40
  • 1
    @JohnBollinger I thought about it again, and it *does* in fact introduce a bug: while double-checking for end-of-file is wasteful but harmless, if any other error occurs, the program will loop infinitely. Let me second your previous comment ;) – Quentin Nov 04 '16 at 13:43
  • @vatsal511 I posted a possible solution below, from what I understand of the question. – RoadRunner Nov 04 '16 at 13:46

4 Answers4

1

I propose like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { IP = 0, PORT = 1};

int main(void){
    FILE *fp;
    char result[2][2][16];//2 lines, 2 kinds, 16:XXX.XXX.XXX.XXX+NUL
    const char *s = "-";//delimiter
    char *value, line[128];
    int i=0;

    fp = fopen("test.txt", "r");
    if (fp == NULL) {
        printf("File doesn't exist\n");
        exit(EXIT_FAILURE);
    }
    while(i < 2 && fgets(line, sizeof(line), fp)){
        value = strtok(line, s);
        strcpy(result[i][IP], value);
        printf("IP : %s\n",result[i][IP]);

        value = strtok(NULL, s);
        strcpy(result[i][PORT], value);
        printf("PORT : %s\n",result[i][PORT]);
        i++;
    }
    puts("");
    for (int k=0;k<2;k++){
        for (int j=0;j<2;j++){
            printf("%s\n",result[k][j]);
        }
    }
    fclose(fp);

    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • when im trying to compare `result[k][j]` (in the final loop) to some string like `192.168.1.1`, i'm unable to do that. Why is that so.? – vatsal511 Nov 04 '16 at 16:19
  • @vatsal511 I don't get you. `strcmp(result[k][j], "192.168.1.1") == 0` is true when k : 0, j : 0. – BLUEPIXY Nov 04 '16 at 20:31
1

What you are doing wrong is that you are assigning "value" pointer to elements of "result" array. In your implementation, all the elements of "result" just mirror the value of "value" pointer. Therefore, when you change the value of "value", you also change all the "result" elements.

Because of that, you should use strcpy function after allocating memory for the specific "result" element.

value = strtok(str, s);
result[i][0]=malloc(strlen(value) + 1);
strcpy(result[i][0], value);
Enver Evci
  • 186
  • 6
  • Not working... Tried what you asked me to. result[i][0]=malloc(strlen(value) + 1); is being shown illegal – vatsal511 Nov 04 '16 at 14:11
0

When you want to keep-copy strings you have to use the function strcpy()

Instead of result[i][x] = value you should do the following

strcpy(result[i][x], value);

Edit: Before the strcpy you have to use malloc to allocate memory for the result[i][x] string. eg:

result[i][0] = malloc(10 * sizeof(char));
elikatsis
  • 479
  • 1
  • 3
  • 8
0

I suggest using malloc for allocating space for each ip and port, and freeing them at the end with free. Additionally, a struct might be handy here, if you have bigger text files in the future that you want to use.

The code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define COLS 2
#define MAXCHAR 10
#define BUFFSIZE 128

void exit_if_null(void *ptr, const char *msg);

int
main(void) {
    FILE *filename;
    char *result[COLS][MAXCHAR+1];
    char buffer[BUFFSIZE];
    char *ip, *port;
    int row, i = 0;

    filename = fopen("ips.txt", "r");

    if (filename == NULL) {
        fprintf(stderr, "%s\n", "Error reading file!\n");
        exit(EXIT_FAILURE);
    } else {
        while (fgets(buffer, BUFFSIZE, filename) != NULL && i < 2) {
            ip = strtok(buffer, "-");
            port = strtok(NULL, "\n");

            result[i][0] = malloc(strlen(ip)+1);
            exit_if_null(result[i][0], "Initial Allocation");

            result[i][1] = malloc(strlen(port)+1);
            exit_if_null(result[i][1], "Initial Allocation");

            strcpy(result[i][0], ip);
            strcpy(result[i][1], port);

            i++;
        }
    }

    for (row = 0; row < i; row++) {
        printf("%s\n", result[row][0]);
        printf("%s\n", result[row][1]);

        free(result[row][0]);
        free(result[row][1]);

        result[row][0] = NULL;
        result[row][1] = NULL;
    }

    return 0;
}

void
exit_if_null(void *ptr, const char *msg) {
    if (!ptr) {
        printf("Unexpected null pointer: %s\n", msg);
        exit(EXIT_FAILURE);
    }
}
RoadRunner
  • 25,803
  • 6
  • 42
  • 75