Tworzenie lancucha na podstawie istniejacego lancucha

0
  1. Mam swiadomosc, ze getline nie jest w ANSI C.
  2. Kod jest w C99.
  3. Moj cel jest nastepujacy - ze standardowego wejscia czytam sobie lancuchy znakow dowolnej dlugosci. Jeżeli znak to ~ to na jego miejscu chce wstawic dowolny string np. "gotit". W przeciwnym wypadku pozostawiam bez zmian. Uznalem, ze najlatwiej bedzie to zrobic przez utworzenie zupelnie nowego lancucha od podstaw niz modyfikowanie istniajacego.
  4. Podczas tworzenia nowego lancucha biore pod uwage, ze potrzeba zaalokowac nastepujaca ilosc bajtow:
  • dla kazdego znaku nie bedacego ~ po 1 bajt (ilosc znakow roznych od ~ sprawdzam napisana do tego celu funkcja)
  • dla znaku bedacego ~ wrzucam ilosc znakow dla lancucha, ktory chce wstawic
  • do tego +1
  1. Kopiowania lancucha dokonuje w petli.
  • w przypadku gdy dziala przepisywanie pojedynczego znaku to przesuwam wskazniki o 1
  • w przypadku, gdy dziala strcat, wskaznik z ktorego czytam przesuwam o 1, a ten do ktorego dopisuje o wartosc rowna dopisanemu slowu
  1. Nowo utworzony lancuch znakow nalezy zakonczyc znakiem o numerze 0. Wiec przepisuje ta wartosc ostatniemu elementowi.
  2. To nie dziala, nie wiem co robie zle, wszelkie wskazowki mile widziane.
#define _WITH_GETLINE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int strlennochar(const char* str, const char ch)
{
  int number = 0;
  while(*str++) {
    if(*str != ch)
      ++number;
  }
  return number;
}

int main()
{   
  char* line = NULL; size_t size;
  const char* putstr = "*gotit*";
  int length;

  while(1) {   
    printf("> ");
    getline(&line, &size, stdin);
    
    // delete '/n'
    length = strlen(line);
    line[length-1] = 0;
    --length;
    
    // check for special characters
    int home = 0, env = 0;
    char* ptr = line;
    while(*ptr++) {
      if(*ptr == '$') ++env;
      if(*ptr == '~') ++home;
    }
    ptr = NULL;
    
    int chars = strlennochar(line, '~'); // number of chars diffrent than '~'
    int len = strlen(putstr);
    char* new = NULL;
    if( (new = malloc(chars + (length - chars) * len + 1)) == NULL ) {
      fprintf(stderr, "Malloc!\n");
      exit(1);
    }

    char* nptr = new;
    ptr = line;
    for(ptr; *ptr; ++ptr) {
      if(*ptr != '~') {
	*nptr = *ptr;
	++nptr;
      } else {
	printf("Dolaczono tu!\n");
	strcat(nptr, putstr);
	nptr += len;
      }
    }
    new[chars + (length - chars) * len] = 0;
    
    printf("%s\n", new);
    free(new);
    if(line) free(line);
   }
}

0
    getline(&line, &size, stdin); 
...
    length = strlen(line);

po to getline() zwraca ci size, żebyś nie musiał zaraz potem używać strlen().

if( (new = malloc(chars + (length - chars) * len + 1)) == NULL ) {

ookeeej...

    char* nptr = new;
...
    strcat(nptr, putstr);

jebut! doklejasz tekst na koniec stringa new, ale skąd wiesz gdzie ten koniec jest? nie wiesz, bo malloc nie wyzerował ci pamięci… użyj calloc:

if( (new = calloc(chars + (length - chars) * len + 1, 1)) == NULL ) {
0

Dzięki, zapamiętam jeśli chodzi o size oraz kwestię calloc i strcat.

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