Menghapus karakter baris baru dari input fgets ()

236

Saya mencoba untuk mendapatkan beberapa data dari pengguna dan mengirimkannya ke fungsi lain di gcc. Kodenya kira-kira seperti ini.

printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}

Namun, pada akhirnya saya menemukan \nkarakter baris baru . Jadi jika saya memasukkannya Johnakhirnya mengirim John\n. Bagaimana cara menghapus itu \ndan mengirim string yang tepat.

sfactor
sumber
21
if (!fgets(Name, sizeof Name, stdin))(paling tidak jangan gunakan dua negasi,! dan! =)
4
@Roger Pate "jangan gunakan dua negasi" -> hmmm, jika kita menggali lebih dalam "jangan" dan "negasi" adalah keduanya negasi . ;-). Mungkin "Gunakan if (fgets(Name, sizeof Name, stdin)) {.
chux - Reinstate Monica
3
@ chux, saya yakin maksud Andaif (fgets(Name, sizeof Name, stdin) == NULL ) {
R Sahu
@RSahu Benar : sial !:
chux - Reinstate Monica

Jawaban:

155

Cara yang agak jelek:

char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
    *pos = '\0';
else
    /* input too long for buffer, flag error */

Cara yang agak aneh:

strtok(Name, "\n");

Perhatikan bahwa strtokfungsi tidak berfungsi seperti yang diharapkan jika pengguna memasukkan string kosong (yaitu hanya menekan Enter). Itu membuat \nkarakter utuh.

Ada yang lain juga, tentu saja.

Jerry Coffin
sumber
7
Pustaka runtime C apa pun yang mengetahui utas (artinya, sebagian besar yang menargetkan platform multi-utas), strtok()akan aman utas (ini akan menggunakan penyimpanan lokal utas untuk keadaan 'antar panggilan'). Yang mengatakan, itu masih lebih baik untuk menggunakan strtok_r()varian non-standar (tapi cukup umum) .
Michael Burr
2
Lihat jawaban saya untuk varian yang sepenuhnya aman-thread dan reentrant, mirip dengan strtokpendekatan Anda (dan bekerja dengan input kosong). Bahkan, cara yang baik untuk mengimplementasikannya strtokadalah menggunakan strcspndan strspn.
Tim Čas
2
Sangat penting untuk menangani kasus lain jika Anda berada di lingkungan di mana ada risiko garis yang terlalu panjang. Masukan yang terpotong secara diam-diam dapat menyebabkan bug yang sangat merusak.
Malcolm McLean
2
Jika Anda suka one-liners dan menggunakan glibc, coba *strchrnul(Name, '\n') = '\0';.
twobit
Ketika strchr(Name, '\n') == NULL, selain dari "input terlalu lama untuk buffer, flag error", kemungkinan lain ada: Teks terakhir stdintidak berakhir dengan '\n'atau karakter null tertanam yang jarang dibaca.
chux - Reinstate Monica
440

Mungkin solusi yang paling sederhana menggunakan salah satu fungsi sedikit diketahui favorit saya, strcspn():

buffer[strcspn(buffer, "\n")] = 0;

Jika Anda ingin juga menangani '\r'(katakanlah, jika aliran adalah biner):

buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...

Fungsi menghitung jumlah karakter hingga mencapai a '\r'atau a '\n'(dengan kata lain, ia menemukan yang pertama '\r'atau '\n'). Jika tidak mengenai apa pun, itu berhenti di '\0'(mengembalikan panjang string).

Perhatikan bahwa ini berfungsi dengan baik bahkan jika tidak ada baris baru, karena strcspnberhenti di a '\0'. Dalam hal ini, seluruh baris hanya diganti '\0'dengan '\0'.

Timas
sumber
30
Ini bahkan menangani yang langka bufferdaripada yang dimulai dengan '\0', sesuatu yang menyebabkan kesedihan untuk buffer[strlen(buffer) - 1] = '\0';pendekatan tersebut.
chux
5
@ chux: Yup, saya berharap lebih banyak orang tahu strcspn(). Salah satu fungsi yang lebih berguna di perpustakaan, IMO. Saya telah memutuskan untuk menulis dan menerbitkan banyak peretasan C yang umum seperti ini hari ini; sebuah strtok_rimplementasi menggunakan strcspndan strspnadalah salah satu yang pertama: codepad.org/2lBkZk0w ( Peringatan: Saya tidak bisa menjamin bahwa itu tanpa bug, itu ditulis dengan tergesa-gesa dan mungkin memiliki beberapa). Saya tidak tahu di mana saya akan mempublikasikannya, tetapi saya bermaksud membuatnya dalam semangat "hacks twiddling" yang terkenal.
Tim Čas
4
Mencari cara untuk memotong dengan kuat . Hal ini tampaknya menjadi hanya benar satu-kapal. lebih cepat - meskipun tidak sesederhana itu. fgets()strcspn()strlen
chux
6
@sidbushes: Pertanyaan, baik dalam judul maupun kontennya, menanyakan tentang baris baru dari fgets()input . Yang selalu juga merupakan baris pertama.
Tim Čas
9
@sidbushes: Saya mengerti dari mana Anda berasal, tetapi saya tidak dapat bertanggung jawab atas hasil pencarian Google untuk istilah tertentu. Bicaralah dengan Google, bukan saya.
Tim Čas
83
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n') 
    name[ln] = '\0';
James Morris
sumber
8
Mungkin akan melempar pengecualian jika string kosong, bukan? Suka indeks di luar jangkauan.
Edward Olamisan
1
@ EdwardOlamisan, string tidak akan pernah kosong.
James Morris
5
@ James Morris Dalam kasus yang tidak biasa fgets(buf, size, ....)-> strlen(buf) == 0. 1) fgets()dibaca sebagai yang pertama chara '\0'. 2) size == 13) fgets()kembali NULLmaka bufisinya bisa apa saja. (Kode OP tidak menguji NULL) Sarankan:size_t ln = strlen(name); if (ln > 0 && name[ln-1] == '\n') name[--ln] = '\0';
chux - Reinstate Monica
2
Bagaimana jika string kosong? lnakan menjadi -1, simpan untuk fakta size_ttidak ditandatangani, sehingga menulis ke memori acak. Saya pikir Anda ingin menggunakan ssize_tdan periksa lnadalah> 0.
abligh
2
@ legends2k: Pencarian untuk nilai waktu kompilasi (terutama nilai nol seperti di strlen) dapat diimplementasikan jauh lebih efisien daripada pencarian char-by-char biasa. Untuk alasan itulah saya menganggap solusi ini lebih baik daripada yang berbasis strchratau strcspn.
AnT
17

Di bawah ini adalah pendekatan cepat untuk menghapus potensi '\n'dari string yang disimpan oleh fgets().
Ini digunakan strlen(), dengan 2 tes.

char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) != NULL) {

  size_t len = strlen(buffer);
  if (len > 0 && buffer[len-1] == '\n') {
    buffer[--len] = '\0';
  }

Sekarang gunakan bufferdan lensesuai kebutuhan.

Metode ini memiliki manfaat sampingan dari lennilai untuk kode selanjutnya. Ini dapat dengan mudah lebih cepat daripada strchr(Name, '\n'). Ref YMMV, tetapi kedua metode bekerja.


buffer, dari aslinya fgets()tidak akan berisi dalam "\n"beberapa keadaan:
A) Garis terlalu panjang untuk bufferhanya charmendahului'\n' disimpan dalam buffer. Karakter yang belum dibaca tetap dalam aliran.
B) Baris terakhir dalam file tidak diakhiri dengan a '\n'.

Jika input telah menanamkan karakter nol '\0'di suatu tempat, panjangnya dilaporkan olehstrlen() menyertakan tidak akan menyertakan '\n'lokasi.


Beberapa masalah jawaban lain:

  1. strtok(buffer, "\n");gagal untuk menghapus '\n'saat bufferini "\n". Dari ini jawaban - diubah setelah jawaban ini untuk memperingatkan batasan ini.

  2. Berikut ini gagal pada kesempatan langka ketika yang pertama chardibaca fgets()adalah '\0'. Ini terjadi ketika input dimulai dengan tertanam '\0'. Lalu buffer[len -1]menjadibuffer[SIZE_MAX] mengakses memori tentunya di luar rentang yang sah buffer. Sesuatu yang mungkin dicoba atau ditemukan oleh peretas dengan bodoh membaca file teks UTF16. Ini adalah keadaan jawaban ketika jawaban ini ditulis. Kemudian non-OP diedit untuk memasukkan kode seperti cek jawaban ini "".

    size_t len = strlen(buffer);
    if (buffer[len - 1] == '\n') {  // FAILS when len == 0
      buffer[len -1] = '\0';
    }
  3. sprintf(buffer,"%s",buffer);adalah perilaku yang tidak terdefinisi: Ref . Lebih lanjut, ini tidak menyimpan spasi putih depan, pemisah, atau tertinggal. Sekarang dihapus .

  4. [Sunting karena jawaban nanti yang bagus ] Tidak ada masalah dengan 1 liner buffer[strcspn(buffer, "\n")] = 0;selain kinerja dibandingkan dengan strlen()pendekatan. Kinerja dalam pemangkasan biasanya bukan masalah yang diberikan kode melakukan I / O - lubang hitam waktu CPU. Jika kode berikut membutuhkan panjang string atau sangat sadar kinerja, gunakan strlen()pendekatan ini . Lain strcspn()adalah alternatif yang baik.

chux - Pasang kembali Monica
sumber
Terima kasih atas jawabannya. Bisakah kita menggunakan strlen(buffer)ketika ukuran buffer dialokasikan secara dinamis menggunakan malloc?
rrz0
@Rrz0 buffer = malloc(allocation_size); length = strlen(buffer);buruk - data di memori yang ditunjuk oleh buffertidak diketahui. buffer = malloc(allocation_size_4_or_more); strcpy(buffer, "abc"); length = strlen(buffer);tidak apa
chux
Terima kasih untuk ini!! Saya mengambil kursus CS dan ini sangat membantu untuk salah satu tugas. saya menghargai jawaban Anda dalam kode sumber.
Nathaniel Hoyt
8

Langsung untuk menghapus '\ n' dari output fgets jika setiap baris memiliki '\ n'

line[strlen(line) - 1] = '\0';

Jika tidak:

void remove_newline_ch(char *line)
{
    int new_line = strlen(line) -1;
    if (line[new_line] == '\n')
        line[new_line] = '\0';
}
Amitabha
sumber
1
Perhatikan itu akan lebih aman untuk digunakan strnlendaripada strlen.
Mike Mertsock
3
Komentar untuk jawaban pertama dalam pertanyaan yang ditautkan menyatakan "Perhatikan bahwa strlen (), strcmp () dan strdup () aman. Alternatif 'n' memberi Anda fungsionalitas tambahan."
Étienne
4
@ Esker tidak, tidak akan. memasukkan ntidak secara ajaib meningkatkan keamanan, dalam hal ini justru akan membuat kode lebih berbahaya. Demikian pula dengan strncpy, fungsi yang sangat tidak aman. Posting yang Anda tautkan adalah saran yang buruk.
MM
3
Ini gagal total untuk string kosong ( ""). Juga tidak strlen()kembali . size_tint
alk
4
ini tidak aman untuk string kosong, ia akan menulis pada indeks -1. Jangan gunakan ini.
Jean-François Fabre
3

Untuk pemangkasan tunggal '\ n',

void remove_new_line(char* string)
{
    size_t length = strlen(string);
    if((length > 0) && (string[length-1] == '\n'))
    {
        string[length-1] ='\0';
    }
}

untuk beberapa pemangkasan '\ n',

void remove_multi_new_line(char* string)
{
  size_t length = strlen(string);
  while((length>0) && (string[length-1] == '\n'))
  {
      --length;
      string[length] ='\0';
  }
}
BEPP
sumber
1
Mengapa bersarang ifsaat Anda cukup menulis satu syarat menggunakan &&? Bahwa whilelingkaran memiliki struktur yang aneh; mungkin saja while (length > 0 && string[length-1] == '\n') { --length; string[length] = '\0'; }.
melpomene
@melpomene terima kasih atas sarannya. Perbarui kodenya.
BEPP
1
Saya akan menyarankan bahwa fungsi pertama adalah lebih alami didefinisikan sebagai: size_t length = strlen(string); if (length > 0 && string[length-1] == '\n') { string[length-1] = '\0'; }. Ini juga mencerminkan definisi kedua yang lebih baik (hanya menggunakan ifalih-alih while).
melpomene
@elpomene terima kasih. Masuk akal. Saya memperbarui kode.
BEPP
1

Cara Newbie saya ;-) Tolong beri tahu saya kalau itu benar. Tampaknya berfungsi untuk semua kasus saya:

#define IPT_SIZE 5

int findNULL(char* arr)
{
    for (int i = 0; i < strlen(arr); i++)
    {
        if (*(arr+i) == '\n')
        {
            return i;
        }
    }
    return 0;
}

int main()
{
    char *input = malloc(IPT_SIZE + 1 * sizeof(char)), buff;
    int counter = 0;

    //prompt user for the input:
    printf("input string no longer than %i characters: ", IPT_SIZE);
    do
    {
        fgets(input, 1000, stdin);
        *(input + findNULL(input)) = '\0';
        if (strlen(input) > IPT_SIZE)
        {
            printf("error! the given string is too large. try again...\n");
            counter++;
        }
        //if the counter exceeds 3, exit the program (custom function):
        errorMsgExit(counter, 3); 
    }
    while (strlen(input) > IPT_SIZE);

//rest of the program follows

free(input)
return 0;
}
Bebek Ling
sumber
1

Langkah-langkah untuk menghapus karakter baris baru dengan cara yang mungkin paling jelas:

  1. Tentukan panjang string di dalam NAMEdengan menggunakan strlen(), header string.h. Perhatikan bahwa strlen()tidak termasuk penghentian \0.
size_t sl = strlen(NAME);

  1. Lihat apakah string dimulai dengan atau hanya menyertakan satu \0karakter (string kosong). Dalam hal ini sladalah 0karena strlen()seperti yang saya katakan di atas tidak menghitung \0dan berhenti pada kemunculan pertama itu:
if(sl == 0)
{
   // Skip the newline replacement process.
}

  1. Periksa apakah karakter terakhir dari string yang tepat adalah karakter baris baru '\n'. Jika demikian, ganti \ndengan a \0. Perhatikan bahwa penghitungan indeks dimulai pada 0jadi kita perlu melakukan NAME[sl - 1]:
if(NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

Catatan jika Anda hanya menekan Enter pada fgets()permintaan string (konten string hanya terdiri dari karakter baris baru) string di NAMEakan menjadi string kosong sesudahnya.


  1. Kita dapat menggabungkan langkah 2. dan 3. bersama-sama hanya dalam satu ifpernyataan dengan menggunakan operator logika &&:
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

  1. Kode yang sudah selesai:
size_t sl = strlen(NAME);
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

Jika Anda lebih suka fungsi untuk menggunakan teknik ini dengan menangani fgetsstring keluaran secara umum tanpa mengetik ulang setiap waktu, berikut adalah fgets_newline_kill:

void fgets_newline_kill(char a[])
{
    size_t sl = strlen(a);

    if(sl > 0 && a[sl - 1] == '\n')
    {
       a[sl - 1] = '\0';
    }
}

Dalam contoh yang Anda berikan, itu akan menjadi:

printf("Enter your Name: ");

if (fgets(Name, sizeof Name, stdin) == NULL) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}
else {
    fgets_newline_kill(NAME);
}

Perhatikan bahwa metode ini tidak berfungsi jika string input telah tertanam \0di dalamnya. Jika itu terjadi maka strlen()hanya akan mengembalikan jumlah karakter sampai yang pertama \0. Tapi ini bukan pendekatan yang umum, karena fungsi membaca string biasanya berhenti pada awalnya \0dan mengambil string sampai karakter nol itu.

Selain dari pertanyaan itu sendiri. Cobalah untuk menghindari negations ganda yang membuat unclearer kode Anda: if (!(fgets(Name, sizeof Name, stdin) != NULL) {}. Anda cukup melakukannya if (fgets(Name, sizeof Name, stdin) == NULL) {}.

RobertS mendukung Monica Cellio
sumber
Tidak yakin mengapa Anda ingin melakukan ini. Tujuan menghapus baris baru bukan untuk mengakhiri string; itu untuk menghapus baris baru. Mengganti dengan \ndengan \0di akhir string adalah cara "menghapus" baris baru. Tetapi mengganti \nkarakter dalam string secara fundamental mengubah string. Tidak jarang memiliki string dengan beberapa karakter baris baru yang disengaja, dan ini akan secara efektif memotong ujung string tersebut. Untuk menghapus baris baru tersebut, isi array harus bergeser ke kiri untuk menulis berlebihan \n.
ex nihilo
@exnihilo Bagaimana seseorang dapat memasukkan string dengan beberapa baris baru di dalamnya dengan menggunakan fgets()?
RobertS mendukung Monica Cellio
Nah, Anda dapat menggabungkan string yang diperoleh dengan beberapa panggilan fgets(). Tapi saya tidak mengerti keberatan Anda: Anda adalah orang yang mengusulkan kode untuk menangani beberapa baris baru.
ex nihilo
@ Exnihilo Anda benar, saya akan terlalu memikirkan strategi. Saya hanya ingin menambahkan cara yang sangat keras tetapi mungkin untuk mendapatkan hasil yang diinginkan.
RobertS mendukung Monica Cellio
@exnihilo Mengedit jawaban saya sepenuhnya dan mengikuti pendekatan utama dengan menggunakan strlendll. Pembenaran karena tidak menjadi duplikat: 1. Penjelasan kode dengan langkah-langkah. 2. Diberikan sebagai solusi berbasis fungsi dan konteks. 3. Petunjuk untuk menghindari ekspresi negasi ganda.
RobertS mendukung Monica Cellio
0

Tim onesebagai liner luar biasa untuk string yang diperoleh melalui panggilan ke gadget, karena Anda tahu mereka mengandung satu baris baru di akhir.

Jika Anda berada dalam konteks yang berbeda dan ingin menangani string yang mungkin berisi lebih dari satu baris baru, Anda mungkin mencari strrspn. Ini bukan POSIX, artinya Anda tidak akan menemukannya di semua Unix. Saya menulis satu untuk kebutuhan saya sendiri.

/* Returns the length of the segment leading to the last 
   characters of s in accept. */
size_t strrspn (const char *s, const char *accept)
{
  const char *ch;
  size_t len = strlen(s);

more: 
  if (len > 0) {
    for (ch = accept ; *ch != 0 ; ch++) {
      if (s[len - 1] == *ch) {
        len--;
        goto more;
      }
    }
  }
  return len;
}

Bagi mereka yang mencari setara Perl chomp di C, saya pikir ini dia (chomp hanya menghapus baris baru).

line[strrspn(string, "\r\n")] = 0;

Fungsi strrcspn:

/* Returns the length of the segment leading to the last 
   character of reject in s. */
size_t strrcspn (const char *s, const char *reject)
{
  const char *ch;
  size_t len = strlen(s);
  size_t origlen = len;

  while (len > 0) {
    for (ch = reject ; *ch != 0 ; ch++) {
      if (s[len - 1] == *ch) {
        return len;
      }
    }
    len--;
  }
  return origlen;
}
Philippe A.
sumber
1
"Karena kamu tahu mereka mengandung satu baris baru di akhir." -> Ia bahkan berfungsi ketika tidak ada '\n'(atau jika stringnya "").
chux - Reinstate Monica
Menanggapi chux komentar pertama Anda, jawaban saya mempertahankannya. Saya harus melempar resetlen strrcspnketika tidak ada \n.
Philippe A.
Kenapa menggunakan goto end;bukan return len;?
chqrlie
@ chqrlie saya harus keluar dari loop 2-level inelegant yang saya lakukan. Kerusakan itu terjadi. Kenapa tidak kebagian goto?
Philippe A.
Anda memiliki dua jenis gotos dalam kode Anda: yang tidak berguna gotoyang dapat diganti dengan returnpernyataan dan mundur gotoyang dianggap jahat. Menggunakan alat strchrbantu implementasikan strrspndan strrcspndengan cara yang lebih sederhana: size_t strrspn(const char *s, const char *accept) { size_t len = strlen(s); while (len > 0 && strchr(accept, s[len - 1])) { len--; } return len; }dansize_t strrcspn(const char *s, const char *reject) { size_t len = strlen(s); while (len > 0 && !strchr(reject, s[len - 1])) { len--; } return len; }
chqrlie
0

Jika menggunakan getlineadalah opsi - Tidak mengabaikan masalah keamanannya dan jika Anda ingin menguatkan pointer - Anda dapat menghindari fungsi string karena getlinemengembalikan jumlah karakter. Sesuatu seperti di bawah ini

#include<stdio.h>
#include<stdlib.h>
int main(){
char *fname,*lname;
size_t size=32,nchar; // Max size of strings and number of characters read
fname=malloc(size*sizeof *fname);
lname=malloc(size*sizeof *lname);
if(NULL == fname || NULL == lname){
 printf("Error in memory allocation.");
 exit(1);
}
printf("Enter first name ");
nchar=getline(&fname,&size,stdin);
if(nchar == -1){ // getline return -1 on failure to read a line.
 printf("Line couldn't be read.."); 
 // This if block could be repeated for next getline too
 exit(1);
}
printf("Number of characters read :%zu\n",nchar);
fname[nchar-1]='\0';
printf("Enter last name ");
nchar=getline(&lname,&size,stdin);
printf("Number of characters read :%zu\n",nchar);
lname[nchar-1]='\0';
printf("Name entered %s %s\n",fname,lname);
return 0;
}

Catatan : [ masalah keamanan ] dengan getlineseharusnya tidak diabaikan.

sjsam
sumber
-1

Fungsi di bawah ini adalah bagian dari pustaka pemrosesan string yang saya pertahankan di Github. Ini menghapus dan karakter yang tidak diinginkan dari string, persis apa yang Anda inginkan

int zstring_search_chr(const char *token,char s){
    if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}

char *zstring_remove_chr(char *str,const char *bad) {
    char *src = str , *dst = str;
    while(*src)
        if(zstring_search_chr(bad,*src))
            src++;
        else
            *dst++ = *src++;  /* assign first, then incement */

    *dst='\0';
        return str;
}

Contoh penggunaan bisa

Example Usage
      char s[]="this is a trial string to test the function.";
      char const *d=" .";
      printf("%s\n",zstring_remove_chr(s,d));

  Example Output
      thisisatrialstringtotestthefunction

Anda mungkin ingin memeriksa fungsi lain yang tersedia, atau bahkan berkontribusi pada proyek :) https://github.com/fnoyanisi/zString

fnisi
sumber
Anda harus menghapus *di *src++;dan membuat bad, tokendan d const char *. Juga mengapa tidak menggunakan strchrbukan zChrSearch? *srctidak bisa '\0'dalam zStrrmvfungsi Anda .
chqrlie
Terima kasih @chqrlie! memperbarui kode untuk mencerminkan saran Anda ..... zstring dimulai sebagai proyek yang menyenangkan dengan tujuan membuat perpustakaan manipulasi string tanpa menggunakan fungsi pustaka standar, karenanya saya tidak menggunakanstrchr
fnisi
1
Menulis " pustaka manipulasi string tanpa menggunakan fungsi pustaka standar " adalah latihan yang bagus, tetapi mengapa memberi tahu orang lain untuk menggunakannya? Jika ada, itu akan menjadi lebih lambat dan kurang teruji dari perpustakaan standar mana pun.
melpomene
Ini melakukan pekerjaan yang berbeda dari apa yang ditanyakan. Ini mungkin dapat digunakan untuk menyingkirkan satu-satunya baris baru, tetapi rasanya seperti berlebihan.
Jonathan Leffler
-1
 for(int i = 0; i < strlen(Name); i++ )
{
    if(Name[i] == '\n') Name[i] = '\0';
}

Anda harus mencobanya. Kode ini pada dasarnya loop melalui string sampai menemukan '\ n'. Ketika ditemukan '\ n' akan digantikan oleh terminator karakter nol '\ 0'

Perhatikan bahwa Anda membandingkan karakter dan bukan string di baris ini, maka tidak perlu menggunakan strcmp ():

if(Name[i] == '\n') Name[i] = '\0';

karena Anda akan menggunakan tanda kutip tunggal dan bukan tanda kutip ganda. Berikut ini tautan tentang tanda kutip tunggal vs ganda jika Anda ingin tahu lebih banyak

Matheus Martins Jerônimo
sumber
2
akan lebih baik jika Anda menjelaskan dan mengedit format kode Anda.
Anh Pham
Biasanya lebih baik menjelaskan solusi daripada hanya memposting beberapa baris kode anonim. Anda dapat membaca Bagaimana cara menulis jawaban yang baik , dan juga Menjelaskan jawaban sepenuhnya berdasarkan kode .
Massimiliano Kraus
1
Saya menyesal ini kontribusi pertama saya di sini. Saya akan memperbaikinya. Terima kasih atas umpan baliknya
Matheus Martins Jerônimo
3
Tidak efisien: for(int i = 0; i < strlen(Name); i++ )akan memanggil strlen(Name)berkali-kali (perubahan loop Name[]) sehingga dengan panjang N, ini adalah O(N*N)solusi. Hanya 1 panggilan ke strlen(Name), jika ada, yang diperlukan untuk memberikan solusi O (N) `. Tidak jelas mengapa int idigunakan size_t i. Pertimbangkanfor(size_t i = 0; i < Name[i]; i++ )
chux - Reinstate Monica
@chux Lainnya sepertifor (size_t i = 0; Name[i]; i++) { if (Name[i] == '\n') { Name[i] = '\0'; break; } }
melpomene
-1

Coba yang ini:

        int remove_cr_lf(char *str)
        {
          int len =0;


          len = strlen(str);

          for(int i=0;i<5;i++)
          {
            if (len>0)
            if (str[len-1] == '\n')
            {
              str[len-1] = 0;
              len--;
            }

            if (len>0)
            if (str[len-1] == '\r')
            {
              str[len-1] = 0;
              len--;
            }
          }

          return 0;
        }
Balazs Kiss
sumber
1
len = strlen(str)mungkin meluap: strlenkembali size_t, tidak int. Ada apa dengan persyaratan aneh if (len>0) if (...)? Apakah kamu tidak tahu tentang &&? Jika Anda akan menghapus beberapa instance trailing CR / LF, mengapa membatasi diri hingga 5? Mengapa tidak menghapus semuanya? Mengapa fungsi memiliki inttipe pengembalian ketika selalu kembali 0? Kenapa tidak kembali saja void?
melpomene