Język C ANSI zadanie

0

Mam problem z zadaniem, mianowicie nie mam pojęcia jak wyszukać te liczby i je wydzielić, żeby potem je zamienić i potem znowu wstawić w to samo miejsce

treść:

Użytkownik wprowadza linię zawierającą pewne słowa i podobne oznaczenia  oraz liczby dziesiętne bez znaku, całkowite lub ułamkowe (z przecinkiem oddzielającym część całkowitą od ułamkowej) zakładamy, że takie liczby oddzielone są od innych napisów co najmniej jedną spacją. Przykład:
segment IKEA 250.30.567   wys. 172,5   szerokosc 45 raczka na wysokosci 130
Napisz program, który:

  1. odczytuje i zapisuje wprowadzoną linię
  2. wyszukuje w tekście liczby odpowiadające opisanym wyżej kryteriom (linia może zawierać także inne symbole cyfrowe jak kod produktu powyżej); liczby te traktujemy jako wymiary liniowe podane w centymetrach i zamieniamy na cale (1cal=2,54cm)
  3. program wypisuje analogiczną linię, w której wymiary w centymetrach są zamienione na wymiary w calach zapisane w notacji anglosaskiej (tj. z kropką dziesiętną zamiast przecinka) z dokładnością do 0.1 cala
    W powyższym przykładzie linia wypisana powinna mieć postać"
    segment IKEA 250.30.567   wys. 67.9   szerokosc 17.7 raczka na wysokosci 54.2

Próbowałem na razie coś takiego ale chyba idę w złą stronę

#define IN 1 /*wewnątrz liczby*/
#define OUT 0 /*poza liczbą*/
int main() {
  
    
    char napis[100],liczby[100], *n;
    
    int i, state, k;
    
    k = i = state =OUT;
    
   
    n = gets(napis); /*wczytanie linii tekstu*/
    
    while(napis[i]!='\0')
    {
        if(napis[i] ==' ')
        {
            state = OUT;
        }
    if((state == OUT )&& (napis[i]>='0')&&(napis[i]<='9'))
    {
        state = IN;
    }
        if(state == IN)
        {
            liczby[k] = napis[i];
                  k++;
        }
    }
    
    for(int j=0; j<k; j++)
    {
        printf("%c ",liczby[j]);
    }
   
    return 0;
} ```
2

Najpierw należy odpowiedzieć na kilka pytań:

  1. czy kolejność danych jest stała, czy wys. może wystąpić (lub nie) w róznych miejscach
  2. czy separator dziesiętny jest stały, czy też nie

dodatkowo z uwag, nie używać gets, jak juz fgets.

2

Napisz automat turinga czyli graf gdzie przejściami są rodzaje znaków.
W sumie potrzebujesz 4 rodzaje: isspace(), isdigit(), iscoma() /*samemu napisać*/ i pozostałe.

0
_13th_Dragon napisał(a):

Napisz automat turinga czyli graf gdzie przejściami są rodzaje znaków.
W sumie potrzebujesz 4 rodzaje: isspace(), isdigit(), iscoma() /*samemu napisać*/ i pozostałe.

To jest najłatwiejszy sposób? Bo na razie miałem pierwsze ćwiczenia z C i brzmi to trochę kosmicznie

0

Nadal nie rozumiem. Gdybym napisał tę maszynę, która przesuwałaby się po kolejnych indeksach to co by mi to dało? Jedynie tyle, że pojedyncze cyfry by się zmieniały, a ja potrzebuję w jakiś sposób wydzielić te cyfry jako liczby z pominięciem tych z kropkami i zamienić je i potem wstawić znowu w to samo miejsce

2

Pewnym przejsiciam przypisujesz pewne funkcji, na przykład przejście z isspace do isdigit powinno zapamiętać pozycję rozpoczęcia liczby,
Zaś przejście z isdigit do isspace powinno przeksztalcić wycinek napisu pomiędzy zapamiętaną pozycją a bieżącą na liczbę.

0
  while(napis[i]!='\0')
    {
        if(isspace(napis[i]) != 0)
        {
            state = OUT;
        }
    if((state == OUT )&&(isdigit(napis[i])!=0))
    {
        state = IN;
        poczatek=i;

    }
        if((state == IN)&&(isspace(napis[i])!=0))
        {
          
        }
        i++;
    }

coś takiego i w ostatnim if'ie dokonywać zamiany?

1

Jakbyś dostarczył dostateczny zbiór danych przykładowych, pokazujący wszystkie możliwe przypadki danych wejściowych, to by można było zaproponować jakieś proste rozwiązanie. A tak to dostajesz wróżenie z fusów i uogólnione rozwiązania.

0

Dodałem cała skopiowana treść zadania

1

stany to dobry pomysł, ale ja tu bym zaczął od tego, że możesz mieć kilka stanów

  1. szukasz początku (czyli litery albo cyfry albo końca)
  2. masz literę, traktujesz jako napis do przepisania, szukasz spacji lub końca, znajdziesz przechodzisz w stan 1.
  3. masz cyfrę - szukasz spacji (bądź końca) i sprawdzasz czy jest to liczba wg definicji, czyli czy składa się z cyfr i co najwyżej jednego przecinka, jeśli w stanie 3 napotkasz inny znak niż cyfra, albo drugi przecinek zmieniasz stan na 2
1
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

struct Shared
{
   int saved,current;
   char buff[8*1024];
};
typedef void TransFunc(Shared *shared,int ch);
typedef int CharKind(int ch);
typedef enum { stStart,stDecim,stFract,stText,stEnd } State;
typedef enum { chkSpace,chkDigit,chkComma,chkOther,chkEof,chkNone } CharKindEnum;

void Done(Shared *shared,int ch) { shared->buff[shared->current]=0; }
void Next(Shared *shared,int ch) { shared->buff[(shared->current)++]=ch; }
void Save(Shared *shared,int ch) { shared->saved=shared->current; Next(shared,ch); }
void Comma(Shared *shared,int ch) { Next(shared,'.'); }
void Convert(Shared *shared,int ch)
{ 
   double value;
   Done(shared,0);
   sscanf(shared->buff+shared->saved,"%lf",&value);
   sprintf(shared->buff+shared->saved,"%.1lf",value/2.54);
   shared->current=shared->saved+strlen(shared->buff+shared->saved);
   Next(shared,ch);
}

int iscomma(int ch) { return (ch==','); }
int isendof(int ch) { return (ch==EOF)||(ch==0)||(ch=='\n'); }
CharKindEnum KindOfChar(int ch)
{
   if(isendof(ch)) return chkEof;
   if(isspace(ch)) return chkSpace;
   if(isdigit(ch)) return chkDigit;
   if(iscomma(ch)) return chkComma;
   return chkOther;
}

typedef struct { TransFunc *func; State next; } TransRecord;

TransRecord TransTable[][chkNone-chkSpace]=
            {//  chkSpace           chkDigit        chkComma         chkOther       chkEof
/*stStart*/    {{Next,stStart},    {Save,stDecim}, {Next,stText},   {Next,stText}, {Done,stEnd}    },
/*stDecim*/    {{Convert,stStart}, {Next,stDecim}, {Comma,stFract}, {Next,stText}, {Convert,stEnd} },
/*stFract*/    {{Convert,stStart}, {Next,stFract}, {Next,stText},   {Next,stText}, {Convert,stEnd} },
/*stText*/     {{Next,stStart},    {Next,stText},  {Next,stText},   {Next,stText}, {Done,stEnd}    },
/*stEnd*/      {{Done,stEnd},      {Done,stEnd},   {Done,stEnd},    {Done,stEnd},  {Done,stEnd}    },
            };

State TranslateStep(Shared *sh,State st,int ch)
{
   TransRecord tr=TransTable[st][KindOfChar(ch)];
   tr.func(sh,ch);
   return tr.next;
}

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