Problem z fgets - pomijanie wpisywania

0

Witam. Do napisania mam program, w którym podaję za pomocą fgets napis o dlugości <=99, później napis2 o długości 5 występujący w napisie, który zostanie zastąpiony przez napis3 o długości 5:

#include <iostream>
#include <cstdio>

using namespace std;

void zamien (char napis1[], int i, char napis3[])
{
    napis1[i] = napis3[0];
    napis1[i+1] = napis3[1];
    napis1[i+2] = napis3[2];
    napis1[i+3] = napis3[3];
    napis1[i+4] = napis3[4];
}

int znajdz (char napis1[], char napis2[])
{
    int i=0;
    do
    {
        if (napis1[i]==napis2[0] && napis1[i+1]==napis2[1] && napis1[i+2]==napis2[2] && napis1[i+3]==napis2[3] && napis1[i+4]==napis2[4])
            return i;
        else
            i++;
    } while (napis1[i]!='\0');
}

int main()
{
    char napis1[100];
    char napis2[6];
    char napis3[6];
    cout << "Enter a string: " << endl;
    fgets (napis1,sizeof(napis1),stdin);
    cout << "Enter a string to change from: " << endl;
    fgets (napis2,sizeof(napis2),stdin);
    cout << "Enter a string to change to: " << endl;
    fgets (napis3,sizeof(napis3),stdin);
    int i = znajdz (napis1,napis2);
    zamien (napis1,i,napis3);
    cout << napis1;
    return 0;
}

Cały szkopuł tkwi w części:

    fgets (napis1,sizeof(napis1),stdin);
    cout << "Enter a string to change from: " << endl;
    fgets (napis2,sizeof(napis2),stdin);
    cout << "Enter a string to change to: " << endl;
    fgets (napis3,sizeof(napis3),stdin);

A mianowicie - wpisuję pierwszy napis, następnie drugi, ale program "pomija" wpisywanie napisu trzeciego - przechodzi od razu do następnych linii programu. Jak sobie z tym poradzić?

2

brakuje return więc masz Undefined Behavior.
U mnie sie kończy to crashem.

Takie rzeczy wyłapuję się po pierwsze opcją -Wall po drugie za pomocą debuggera.

1

Nie wpisujesz przypadkiem 6 znaków za drugim razem?
Pamiętaj że zawsze musisz mieć miejsce na \0.

0

@MarekR22:

Chodzi o return w funkcji znajdź w przypadku braku odpowiedniego i?
Jeżeli tak no to fakt, ale skoro program się kompiluje na CodeBlocksie, to ewentualny błąd nie powinien wyskoczyć dopiero przy właśnie braku i? Wpisywanie odbywa się jeszcze przed wykonaniem obu funkcji.

A co do wychwytywania blędów na takie sposoby - jestem początkujący i jeszcze nie mam pojęcia jak to się robi :( Proszę o wyrozumialosc

@atmal

Nie, na pewno wpisuję dobrze. Dodam, że jeżeli jako napis 2 wpisze jakiś wyraz 4 znakowy, to wtedy pojawia się możliwość wpisania napisu3 - jeżeli jest 5 znaków (tak jak ma być), to program pomija wpisywanie napisu 3.

1

@marko2255:
To dlatego że fgets zjada \n i pakuje Ci do bufora. Czyli do 4 znaków jest ok bo 5 to \n a 6 \0. Ale gdy wpiszesz już 5 znaków wtedy nie ma miejsca na \0.

1

odpowiedź @atmal dała mi do myślenia i wiem już w czym problem.
Jak wpisujesz 5 znaków, to to idealnie pasuje do rozmiaru tablicy.
Efekt jest taki, że w takim wypadku fgets nie wczyta znaków końca linii.
Gdy wczytujesz następny napis, to zostanie wczytany jedynie znak końca linii z poprzedniego napisu.
Dlatego właśnie:

program "pomija" wpisywanie napisu trzeciego

1

Jak już używać C++ to po co męczyć się z C?

std::string s, f, r;
if (std::getline(cin, s))
    && std::getline(cin, f))
    && std::getline(cin, r))
{
    auto i = s.find(f);
    if (i != std::string::npos)
    {
        s.replace(i, f.length(), r);
    }
    std::cout << s << endl;
}
0

Oczywiście, byłoby lepiej, ale jest to zadanie na zajęcia z programowania, i w poleceniu jest wskazane, by używać fgets do wprowadzenia napisów.

Dzięki za pomoc ;D Zmieniłem wielkość tablicy napisu2 na 7, i teraz wszystko działa!

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