Ali Koca
Ali Koca

Reputation: 17

How to count spaces and pass characters or newline?

I was writing a tool that replaces enough spaces with tab, but it counts more spaces than expected.

Algorithm should count spaces until seeing character or newline, if there is a character or newline, it passes to next element of string; but unfortunately continues to count spaces instead of passing newline or character.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#define BUFFER_SIZE 100

int set_tab_init_arg(char *filename, int space_size)
{
        struct stat filest;
        FILE *fp = fopen(filename, "r+");
        int fd = fileno(fp);
        int line = 0, space = 0, var = 0, offset = 0;

        if (fstat(fd, &filest) < 0)
                return -1;

        char *filecontent = (char*)malloc(filest.st_size);
        char buff[BUFFER_SIZE];

        if (fp == NULL) {
                fprintf(stderr, "cyntax: invalid file pointer!\n");
                return -1;
        }

        while (fgets(buff, BUFFER_SIZE, fp) != NULL)
                strcat(filecontent, buff);

        char *tmpcontent, *willbewrited = filecontent;

        for (int x = 0; x < strlen(filecontent); x++) {
                if (filecontent[x] == 32) { 
                        printf("space\n"); 
                        space++; 
                }

                else if (filecontent[x++] == 10) { 
                        line++; 
                        printf("newline: %d\n", line); 
                        space = 0; 
                }

                else {
                        printf("char\n");
                        x++;
                        var++;
                }

                if (space == space_size) {
                        replace_spaces_to_tab();
                        printf("space = space_size\n");
                }

                filecontent++, offset++;
        }
}

here is file I tested on:

 a
 b
 c
 d
 e f g
 c h e
 p ğ a

and debug result is here (stdout):

space
newline: 1
newline: 2
newline: 3
newline: 4
space
space
space = space_size
newline: 5
space
space
space = space_size
newline: 6
space
char

I executed with parameters: ./cyntax try -t 2

Note-1: try is file and -t 2 gets space size for converting enough spaces to tab.

Note-2: I used printf() function for debugging.

Upvotes: 0

Views: 259

Answers (1)

frightenedpigeon
frightenedpigeon

Reputation: 64

I think your problems were created by:

  • incrementing x additionally in the for loop x++; ( I believe this was already fixed in the comments)
  • incrementing the filecontent pointer at the end of your for loop filecontent++;

I code on linux. That's why I had to change your line break detection slightly. (Do line endings differ between Windows and Linux?). not relevant to your problem though...

My Solution

I markes my changes with CHANGE::

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#define BUFFER_SIZE 100

int set_tab_init_arg(char *filename, int space_size)
{
        struct stat filest;
        FILE *fp = fopen(filename, "r+");
        int fd = fileno(fp);
        int line = 0, space = 0, var = 0, offset = 0;

        if (fstat(fd, &filest) < 0)
                return -1;

        char *filecontent = (char*)malloc(filest.st_size);
        char buff[BUFFER_SIZE];

        if (fp == NULL) {
                fprintf(stderr, "cyntax: invalid file pointer!\n");
                return -1;
        }

        while (fgets(buff, BUFFER_SIZE, fp) != NULL)
                strcat(filecontent, buff);

        char *tmpcontent, *willbewrited = filecontent;

        for (int x = 0; x < strlen(filecontent); x++) {
                if (filecontent[x] == 32) { 
                        printf("space\n"); 
                        space++; 
                }

                else if (filecontent[x] == 10) { // CHANGE:: on linux. for windows filcontent[x++] is right :)
                        line++; 
                        printf("newline: %d\n", line); 
                        space = 0; 
                }

                else {
                        printf("char\n");
                        //x++; //CHANGE:: removed else you would skip after chars
                        var++;
            space = 0;
                }

                if (space == space_size) {
                       // replace_spaces_to_tab(); //CHANGE:: commented just to be able to compile
                        printf("space = space_size\n");
                }

               // filecontent++; //CHANGE:: removed else you would skip chars
            offset++;
        }
}

//CHANGE:: needed a main...
int main(){


set_tab_init_arg("try",2 );

}


compiled with gcc on linux fedora:

gcc -Wall -Wextra -g -o a.out main.c

testfile:

 a
 b
 c
 d
 e f g
 c h e
 p ğ a


my output to your testfile:

% ./a.out                             
space
char
newline: 1
space
char
newline: 2
space
char
newline: 3
space
char
newline: 4
space
char
space
char
space
char
newline: 5
space
char
space
char
space
char
newline: 6
space
char
space
char
char
space
char
newline: 7

Upvotes: 1

Related Questions