Reversing each line of a file in C

5

I'm trying to make a program that basically strings each line of a text file in reverse order, that is, the line is shown from end to end. For example, the line 'hello world!' is displayed in the form '! dlrow olleh'

So far I have this code done:

#define _GNU_SOURCE
#define ERR_IO 1

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <stdint.h>

#include "debug.h"
#include "memory.h"
#include "invert_line_file.h"

void invert_line_file(char *filename){

    FILE *fptr = NULL;
    fptr = fopen(filename, "r");    

    if (fptr==NULL){
        ERROR(1, "Erro ao abrir o ficheiro %s", filename);
    }

    int cont=0;
    char *line=NULL;
    size_t line_size=0;
    int i=0, j=0;
    int size;

    printf("\nFile '%s'", filename);
    while (getline(&line, &line_size, fptr)!=-1){
        size=strlen(line);
        while((size_t)i<strlen(line)){
            for (i=0 ; (line[i]!='
Gabriel
Joao
Pedro
Rui
Andre
Joni
Goncalo
Ana
Silvia
Maria
') ; i++){ for (j=0; j<i; j++){ char tmp = line[j]; line[j] = line[size-1-j]; line[size-1-j] = tmp; } } i++; } i=0; j=0; cont++; printf("\n%x: '%s'", cont, line); } if (!feof(fptr)){ ERROR(1, "Erro ao ler do ficheiro %s", filename); } }

My problem is that for example with a file (data.txt) with the following content:

File 'data.txt'
1: '
leirbaG'
2: 'Joao
'
3: '
ordeP'
4: '
iuR'
5: '
erdnA'
6: 'Joni
'
7: '
olacnoG'
8: '
anA'
9: 'Silvia
'
a: '
airaM'

The output at the end of running the program is:

#define _GNU_SOURCE
#define ERR_IO 1

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <stdint.h>

#include "debug.h"
#include "memory.h"
#include "invert_line_file.h"

void invert_line_file(char *filename){

    FILE *fptr = NULL;
    fptr = fopen(filename, "r");    

    if (fptr==NULL){
        ERROR(1, "Erro ao abrir o ficheiro %s", filename);
    }

    int cont=0;
    char *line=NULL;
    size_t line_size=0;
    int i=0, j=0;
    int size;

    printf("\nFile '%s'", filename);
    while (getline(&line, &line_size, fptr)!=-1){
        size=strlen(line);
        while((size_t)i<strlen(line)){
            for (i=0 ; (line[i]!='
Gabriel
Joao
Pedro
Rui
Andre
Joni
Goncalo
Ana
Silvia
Maria
') ; i++){ for (j=0; j<i; j++){ char tmp = line[j]; line[j] = line[size-1-j]; line[size-1-j] = tmp; } } i++; } i=0; j=0; cont++; printf("\n%x: '%s'", cont, line); } if (!feof(fptr)){ ERROR(1, "Erro ao ler do ficheiro %s", filename); } }
    
asked by anonymous 07.06.2018 / 21:19

1 answer

3

Your inversion of string is too complex:

while((size_t)i<strlen(line)){
    for (i=0 ; (line[i]!='
for (i = 0, j = size-1; i < size/2; ++i, j--){
    char tmp = line[j];
    line[j] = line[size-1-j];
    line[size-1-j] = tmp;
}
') ; i++){ for (j=0; j<i; j++){ char tmp = line[j]; line[j] = line[size-1-j]; line[size-1-j] = tmp; } } i++; } i=0; j=0;

You have 3 loops to do an inversion. To be honest I could not even figure out exactly how you got to these 3 loops because only 1 solves your problem:

line[strcspn(line,"\n")] = '
while (getline(&line, &line_size, fptr)!=-1){
    line[strcspn(line,"\n")] = '
File 'data.txt'
1: 'leirbaG'
2: 'oaoJ'
3: 'ordeP'
4: 'iuR'
5: 'erdnA'
6: 'inoJ'
7: 'olacnoG'
8: 'anA'
9: 'aivliS'
a: 'airaM'
'; size=strlen(line); for (i = 0, j = size-1; i < size/2; ++i, j--){ char tmp = line[j]; line[j] = line[size-1-j]; line[size-1-j] = tmp; } cont++; printf("\n%x: '%s'", cont, line); }
';

Notice that I go up to half the string and change directly with the corresponding caratere from the end. I also did not return i and j to 0 because for is in charge of initializing these two variables with the values that interest.

The other problem has to do with the line break that was in the string when you read it with getline . This gives that Enter the more you see on the output. You can solve this problem by looking for the \n that is there and putting the terminator in the same place:

while((size_t)i<strlen(line)){
    for (i=0 ; (line[i]!='
for (i = 0, j = size-1; i < size/2; ++i, j--){
    char tmp = line[j];
    line[j] = line[size-1-j];
    line[size-1-j] = tmp;
}
') ; i++){ for (j=0; j<i; j++){ char tmp = line[j]; line[j] = line[size-1-j]; line[size-1-j] = tmp; } } i++; } i=0; j=0;

The function strcspn finds the position of a given text in a string and returns it. If it does not find anything it returns the size of the string.

This would have to be applied before the inversion, passing its code of while(getline..) to be:

line[strcspn(line,"\n")] = '
while (getline(&line, &line_size, fptr)!=-1){
    line[strcspn(line,"\n")] = '
File 'data.txt'
1: 'leirbaG'
2: 'oaoJ'
3: 'ordeP'
4: 'iuR'
5: 'erdnA'
6: 'inoJ'
7: 'olacnoG'
8: 'anA'
9: 'aivliS'
a: 'airaM'
'; size=strlen(line); for (i = 0, j = size-1; i < size/2; ++i, j--){ char tmp = line[j]; line[j] = line[size-1-j]; line[size-1-j] = tmp; } cont++; printf("\n%x: '%s'", cont, line); }
';

With these two changes you already have the output you want:

%pre%     
07.06.2018 / 22:22