How to insert a ";" at the end of the string, program in c

Asked

Viewed 379 times

0

I wonder what I should do for the ";" in the print appear afterward of string and not before. I’m new to programming and I’d like to appeal to your help.

Thank you

Input

Linha1
Linha2
Linha3
Linha4

Expected output

Produtos:
- Linha3;
- Linha4;
- Linha2;
- Linha1;

Output obtained

Produtos:
- Linha1
;- Linha2
;- Linha3
;- Linha4
;

Code

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

typedef struct linha {
  char *produtos;
  struct linha *prev;
} linha;

FILE *file;   
int main() {

  linha *tail = NULL;
  file = fopen("text.txt","r");
  char linha1[255];

  while (fgets(linha1,255,file)!=NULL) {
    linha *l1 =(linha*) malloc(sizeof(linha));
    l1->produtos =(char*) malloc(strlen(linha1)+1);
    strcpy(l1->produtos,linha1);
    l1->prev = tail;
    tail = l1;
  }

  linha *current;
  current = tail;
    printf("Produtos:\n");
  while (current != NULL) {
    printf("- %s;",current->produtos);
    current = current->prev;
  }
  return 0;

}

3 answers

1

Edited, because if the file being read did not end with a line break ('\n'), the last character would be deleted. A test is placed to verify that the last character of the line read is '\n' before replacing.

As the user72726 explained in his reply, the fgets function includes line advance when reading from the file ('\n'). At first I thought of inserting the semicolon when reading the file, but this limits some other treatment you may want to do.

I suggest taking this line forward while reading from the archive

while (fgets(linha1,255,file)!=NULL) {
  linha *l1 =(linha*) malloc(sizeof(linha));
  if (linha1[strlen(linha1) - 1] == '\n') // testa se o último caractere é \n
    linha1[strlen(linha1) - 1] = '\0'; // troca o \n pelo char null
  l1->produtos =(char*) malloc(strlen(linha1)+1);
  strcpy(l1->produtos,linha1);
  l1->prev = tail;
  tail = l1;
}

and then add the semicolon and the line advance when displaying on the screen

while (current != NULL) {
  printf("- %s;\n",current->produtos);
  current = current->prev;
}

It works because functions that handle strings stop when finding a null character - see the ref. from the following link strcpy, at the end of the first sentence "including the terminating null Character (and Stopping at that point)".

Note that if done sizeof(linha1) will look different from strlen(linha1), the normal, if I’m not mistaken, is the difference being 1 but here will be 2 because linha1 is a pointer that at the end has two null characters instead of 1, which strlen does not count.

The above paragraph is incorrect because sizeof(linha1) in the case of this program will always be 255, as it is the size allocated in the declaration.

One important thing, though off the subject of the question, is to release all the memory you use. So, if it were me, for each malloc I would put a memfree on the program even if the program was to close soon after.

References (other functions appear in the menu on the left): http://www.cplusplus.com/reference/cstring/strlen/ http://www.cplusplus.com/reference/cstring/strcpy/

  • adding the null character will cause memory leakage, because so you are discarding the \0 original. Although it is not much (1byte), it is good practice to return all memory to OS.

  • @user72726 I don’t think so, because the compiler has information about how much memory the pointer (line1) uses, it doesn’t depend on string handling methods to know how much memory it needs to release, it already knows. We’re only fooling the functions that mess with the string, not the memory management.

  • @user72726 I hadn’t even noticed, the array line1 is declared with size 255, simpler yet, no problem in changing end-of-line character by null. 255 bytes of , content will always be released. In reality this program has no memfree, I would definitely put one for each malloc. I’ll include a comment on that in the reply right now.

0

The function fgets returns all line characters, including the end-of-line character itself - \n (obviously, it is the last character of the string returned). And that is why the printing is not being done in the desired way.

Then, you could choose to replace the last character of the string with a blank.

Ex:

linha1[strlen(linha1) -1 ] = ' ';
strcpy(l1->produtos,linha1);
  • In addition to the changes you suggested, it is necessary to put a \n at the end of the print. Additionally, it would be nice to add a link to the function documentation fgets, such as http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html

  • @merchant, fgets in cpprference has more friendly information.

  • @Márioferoldi manuals POSIX (opengrup) are usually more accurate and compatible with the standard, with less emphasis on extensions.

  • @merchant, I understand your point. cppreference does not document extensions.

-1

The code entered in the question is not in C style++.

I rewrote using C++ libraries. Compiled with:

g++ -Std=c++11 stackoverflow.cpp -o stackoverflow

#include <iostream>
#include <fstream>

using namespace std;

int main() {

    ifstream entrada("entrada.txt");
    string linha;

    while (getline(entrada, linha)) {
        cout << " - " << linha << ";" << endl;
    }

    return 0;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.