Zamiana \t na odpowiedniki spacji

0

Program powinien zamieniac tabulatiry na spacje tj.np. 'b','\t','c' powinien zamienic na 'b' ' ' ' ' ' 'c' powinien działać prawidłowo ale tak się nie dzieje, 'a' nie wpisuje się do nowej tablicy.

#include <stdio.h>
#define N 15
#define tabulation 3

void zamiana(char tab[], char newtab[])
{

    int i, j = 0, actual_index;
    for (i = 0; i < N - 1; ++i) {
        if (tab[i] == '\t') {
            j = 0;
            while (j < tabulation) {
                newtab[i + actual_index + j] = ' ';
                ++j;
            }
            actual_index = j;
        }
        else
            newtab[i + actual_index] = tab[i];
    }
    newtab[i + actual_index + 1] = '\0';
}

int main(int argc, char* argv[])
{
    char tab[N] = { 'b', '\t', 'a', '\t', '\t', [N - 1] = '0' };
    char newtab[N] = {[N - 1] = '0' };

    zamiana(tab, newtab);

    printf("%s", newtab);
    return 0;
}
 
0

actual_index = j; Na pewno? A co jeśli tabulatorów jest kilka? Nie powinno być raczej actual_index+=j;?

EDIT: Prawdziwy problem: Jak i się równa 2, czyli wskazuje na literkę a, to wtedy i+actual_index równa się 5. A powinno równać się 4, bo wtedy newtab jest równe {'\b', ' ', ' ', ' '}. Rada: Trzymaj actual_index jako rzeczywiście indeks ostatniego elementu newtab, będzie prościej ominąć podobne błędy w rachunkach. Czyli, za każdym razem gdy wstawiasz literkę do newtab, zwiększasz actual_index o 1.

0
 #define TABSIZE 4

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

char *tabs_to_spaces(char *str)
{
  size_t len = strlen(str);
  
  size_t n_of_tabs = 0;
  for(int i = 0; i < len; i++) if(str[i]=='\t') n_of_tabs++;
  
  size_t n_len = len + TABSIZE*n_of_tabs;
  
  char *n_str = malloc(n_len+1); if(n_str == NULL) return n_str;
  
  for(int i=0, j=0; i < len; i++)
    if(str[i]=='\t')
      for(int k=0;k<TABSIZE;k++) n_str[j++] = ' ';
    else n_str[j++] = str[i];
  n_str[n_len] = '\0'; return n_str;
}

char *read_line(void)
{
  size_t act_siz = 0;
  size_t max_siz = 16;
  
  char *str = malloc(max_siz); if(str == NULL) return str;
  
  while(
    fgets(str+act_siz, max_siz-act_siz, stdin) != NULL && 
    str[(act_siz = strlen(str))-1] != '\n'
  ) if(act_siz+1 == max_siz) {
    char *nstr = realloc(str, max_siz*=2);
    if(nstr == NULL) {free(str); return str;}
    str = nstr;
  }
  
  if(ferror(stdin)) {free(str); return str;}
  
  if(str[act_siz-1]=='\n') str[--act_siz] = '\0'; return str;
}

int main()
{
  char *str = read_line();
  if(str == NULL) return EXIT_FAILURE;
  
  char *spstr = tabs_to_spaces(str);
  if(spstr == NULL) {free(str); return EXIT_FAILURE;}
  
  if(puts(spstr)==EOF) {free(spstr); free(str); return EXIT_FAILURE;}
  
  free(spstr); free(str); return EXIT_SUCCESS;
}
    

Mądrzejszych ode mnie proszę o komentarz do powyższego.

0

@bartek164: Po co dwie pętle i actual_index?

0
#include <stdio.h>
#define N 15
#define tabulation 3

void zamiana(char tab[], char newtab[])
{

    int i, j = 0, actual_index;
    for (i = 0; i < N - 1; ++i) {
        if (tab[i] == '\t') {
            j = 0;
            while (j < tabulation) {
                newtab[i + actual_index + j] = ' ';
                ++j;
            }
            actual_index += j-1;
        }
        else
            newtab[i + actual_index] = tab[i];
    }
    newtab[i + actual_index + 1] = '\0';
}

int main(int argc, char* argv[])
{
    char tab[N] = { 'b', '\t', 'a', '\t', '\t', [N - 1] = '\0' };
    char newtab[N] = {[N - 1] = '\0' };

    zamiana(tab, newtab);

    printf("%s", newtab);
    return 0;
}
 

Zrobiłem hyba dobrze

0

to tabulatory na spacje czy PRZECINKI i tabulatory.

 
void tabtospace( char *str )  {

  while( *++str ) {

    if( *str == '\t' )  *str = ' ';

  }

}

1

Wydaje mi się, że dobrze (tylko wciąż nie inicjalizujesz actual_index!!)

Ale czy nie prościej tak?

void zamiana(char tab[], char newtab[])
{
   int i, j=0;
   for(i = 0; i < N-1; i++) {
    if(tab[i] == '\t') {
      for(int k = 0; k < tabulation; k++) {
        newtab[j] = ' ';
        j++;
      }
    } else {
      newtab[j] = tab[i];
      j++;
    }
  }
0

dziękuje za help. ;)

0

Czyli za jeden tab 3 spacje tak? To lepiej zwrócić nowy element alokowany. Niestety jak coś jeszcze zjeb*** to jużn ie poprawie bo zaraz wychodze.

 char* tabto3xspace( const char *const str )  {

  const char *ptr = str;
  size_t newsize = 1; // we count nul allready
  for(; *ptr; ptr++ )   {

    if( *ptr == '\t' )   newsize += 3;
    else newsize++;

  }
  ptr = str;
  char *const newstr = malloc( newsize );
  char *newptr = newstr;
  for(; *ptr; ptr++ )  {

    if( *ptr == '\t' )  {
       
        memset( newptr, ' ', 3 );
       newptr += 3;
       
    }  
    else  *newptr++ = *ptr;  

 }
 newptr = '\0';
 
 return newstr;

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1