it-swarm-id.com

Apa cara paling sederhana untuk mendapatkan input pengguna di C?

Tampaknya ada BANYAK cara Anda bisa mendapatkan input pengguna dalam C. 

Apa cara termudah yang membutuhkan sedikit kode?

Pada dasarnya saya perlu menampilkan ini:

Enter a file name: Apple.text

Pada dasarnya saya perlu menanyakan nama file kepada pengguna. Jadi saya butuh sesuatu yang hanya mendapatkan satu kata yang akan dimasukkan oleh pengguna. 

20
antonpug

Yang paling sederhana "benar" cara mungkin yang ini, diambil dari kertas Bjarne Stroustrup Learning Standard C++ As A New Language .

(Catatan: Saya mengubah kode Bjarne untuk memeriksa isspace() bukan hanya akhir baris. Juga, karena komentar @ matejkramny, untuk menggunakan while(1) alih-alih while(true)... dan selama kita cukup sesat untuk mengedit Stroustrup's kode, saya sudah memasukkan dalam komentar C89 bukannya gaya C++ juga. :-P)

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

void quit() /* write error message and quit */
{
    fprintf(stderr, "memory exhausted\n");
    exit(1);
}

int main()
{
    int max = 20;
    char* name = (char*) malloc(max); /* allocate buffer */
    if (name == 0) quit();

    printf("Enter a file name: ");

    while (1) { /* skip leading whitespace */
        int c = getchar();
        if (c == EOF) break; /* end of file */
        if (!isspace(c)) {
             ungetc(c, stdin);
             break;
        }
    }

    int i = 0;
    while (1) {
        int c = getchar();
        if (isspace(c) || c == EOF) { /* at end, add terminating zero */
            name[i] = 0;
            break;
        }
        name[i] = c;
        if (i == max - 1) { /* buffer full */
            max += max;
            name = (char*) realloc(name, max); /* get a new and larger buffer */
            if (name == 0) quit();
        }
        i++;
    }

    printf("The filename is %s\n", name);
    free(filename); /* release memory */
    return 0;
}

Itu meliputi:

  • melewatkan spasi hingga Anda mencapai input karakter
  • memperluas buffer string secara dinamis agar sesuai dengan string ukuran sewenang-wenang
  • menangani kondisi saat memori tidak dapat dialokasikan

Apakah ada solusi yang lebih sederhana namun rusak, yang bahkan mungkin berjalan sedikit lebih cepat? Benar!!

Jika Anda menggunakan scanf ke dalam buffer tanpa batas pada ukuran read, maka input Anda melebihi ukuran buffer, itu akan membuat lubang keamanan dan/atau crash.

Membatasi ukuran bacaan, katakanlah, hanya 100 karakter unik dari nama file mungkin tampak lebih baik daripada menabrak. Tapi itu bisa lebih buruk; misalnya jika pengguna berarti (...)/dir/foo/bar.txt tetapi Anda akhirnya salah mengartikan input mereka dan menimpa file bernama bar.t yang mungkin mereka pedulikan.

Yang terbaik adalah membiasakan diri sejak dini dalam menangani masalah-masalah ini. Pendapat saya adalah bahwa jika persyaratan Anda membenarkan sesuatu yang dekat dengan logam dan "seperti-C", ada baiknya untuk mempertimbangkan lompatan ke C++. Itu dirancang untuk mengelola dengan tepat keprihatinan ini - dengan teknik yang kuat dan dapat dikembangkan, namun tetap berkinerja baik.

23
HostileFork

scanf tampaknya bekerja di lingkungan yang tidak bermusuhan. Dengan kata lain, Anda membuat program utilitas sederhana untuk diri sendiri.

BUFSIZ biasanya jauh melebihi batas ukuran nama path UNIX.

#include <stdio.h>

int main(void) {
  char str[BUFSIZ];                                                                                                                                                                             

  printf("Enter a file name: ");                                                                                                                                                                
  scanf("%s", str);                                                                                                                                                                             

  printf("You entered: %s\n", str);                                                                                                                                                             
}

Jika Anda perlu mengakumulasi data dalam program yang bisa menjadi target buffer overrun, Anda mungkin perlu sedikit lebih banyak.

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

char * Prompt_and_read(const char * Prompt) {
  char * response;
  char * bufsize;

  printf("%s", Prompt);
  asprintf(&bufsize, "%%%us", BUFSIZ);

  if((response = malloc(BUFSIZ + 1)) == NULL) {
    fprintf(stderr,"out of memory\n");
    exit(1);
  }
  scanf(bufsize, response);
  free(bufsize);
  return response;
}

int main ( void ) {
  char * pathname;

  pathname = Prompt_and_read("Enter a file name: ");
  printf("You entered: [%s]\n", pathname);
  free(pathname);

  return 0;
}
7
karrick
#include <stdio.h>
int main(void)
{
    char file[100];
    printf("File Name?: \n");
    fgets(file, 100, stdin);
    printf("Your input: %s", file);
}
3
Tio Pepe

anda harus menulis fungsi wrapper fgets () Anda sendiri yang membaca sebaris input ke dalam buffer dengan ukuran yang ditentukan dan yang menghilangkan karakter baris baru yang facks () juga berbunyi. Anda juga dapat mengembalikan status apakah seluruh baris dapat masuk ke dalam buffer (mis. adalah baris baru di akhir buffer). Anda seharusnya tidak pernah benar-benar menggunakan scanf atau mendapat kecuali Anda ingin meluap.

EDIT: pikir saya mungkin memberikan beberapa kode dasar:

typedef unsigned char BOOL;
#define TRUE   1
#define FALSE  0

/* wraps fgets, returns FALSE if the whole line couldn't fit into the buffer */
BOOL read_input(char *dest, size_t len)
{
   /* our temp buffer needs to hold the extra new line char (len + 1)
        * should also add error checking to malloc */
   BOOL bSuccess = TRUE;
   size_t total_len = len + 1;
   char *temp = (char*) malloc( total_len * sizeof(char) );

   fgets(temp, total_len, stdin);

   /* if the whole line wasn't read, we'll return FALSE but still copy temp into dest */
   if (temp[strlen(temp) - 1] != '\n')
      bSuccess = FALSE;
   else
      temp[strlen(temp) - 1] = '\0'; /* overwrite the '\n' if it does infact exist */

   strcpy(dest, temp);

   free(temp);
   return bSuccess;
}
1
AusCBloke
#include <iostream>
#include <string>

using namespace std;

int main()
{
    cout << "Enter a file name:";

    string filepath;
    cin >> filepath;
}
1
Ayjay

Gunakan kode sederhana ini

#include"stdio.h"
#include"stdlib.h"
main()
{
    int i=0,j=0;
    char c,buf[100];

start:
    printf("Enter the name:");
    while ( (c=getchar()) != '\n' )
    {
            buf[i++]=c;
            buf[i]='\0';
    }
    if ( buf[0] == '\0')
    {
    printf("invalid name\n");
    goto start;
    }
    else
    printf("Your name is valid\nName = %s\n",buf);
      }                                                                                                                             
0
Q_SaD