سؤال

باستخدام التعليمات البرمجية التالية:

char *name = malloc(sizeof(char) + 256); 

printf("What is your name? ");
scanf("%s", name);

printf("Hello %s. Nice to meet you.\n", name);

يمكن للمستخدم إدخال اسمه ولكن عند إدخال اسم مع مساحة مثل Lucas Aardvark, scanf() فقط يقطع كل شيء بعد Lucas. وبعد كيف أفعل scanf() السماح للمسافات

هل كانت مفيدة؟

المحلول

الناس و خاصة المبتدئين) يجب ألا تستخدم أبدا scanf("%s") أو gets() أو أي وظائف أخرى لا تحتوي على حماية تجاوز سعة مخزنة، إلا إذا كنت تعرف مؤكدا أن المدخلات ستكون دائما بتنسيق محدد (وربما حتى بعد ذلك).

تذكر من ذلك scanf تقف على "المسح المنسق" وهناك القليل الثمينة أقل منسق من البيانات التي تم إدخالها المستخدم. إنه مثالي إذا كان لديك سيطرة كاملة على تنسيق بيانات الإدخال ولكن غير مناسب بشكل عام لإدخال المستخدم.

يستخدم fgets() (أي لديها حماية تجاوز الفضاء العازلة) للحصول على المدخلات الخاصة بك في سلسلة و sscanf() لتقييمه. منذ أن تريد فقط ما دخله المستخدم دون تحليل، لا تحتاج حقا sscanf() في هذه الحالة على أي حال:

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

/* Maximum name size + 1. */

#define MAX_NAME_SZ 256

int main(int argC, char *argV[]) {
    /* Allocate memory and check if okay. */

    char *name = malloc(MAX_NAME_SZ);
    if (name == NULL) {
        printf("No memory\n");
        return 1;
    }

    /* Ask user for name. */

    printf("What is your name? ");

    /* Get the name, with size limit. */

    fgets(name, MAX_NAME_SZ, stdin);

    /* Remove trailing newline, if there. */

    if ((strlen(name) > 0) && (name[strlen (name) - 1] == '\n'))
        name[strlen (name) - 1] = '\0';

    /* Say hello. */

    printf("Hello %s. Nice to meet you.\n", name);

    /* Free memory and exit. */

    free (name);
    return 0;
}

نصائح أخرى

يحاول

char str[11];
scanf("%10[0-9a-zA-Z ]", str);

امل ان يساعد.

يستخدم هذا المثال عمليات البحث المقلوبة، لذلك يحتفظ Scanf في أخذ القيم حتى يواجه " n" - Newline، لذلك يتم حفظ المسافات أيضا

#include <stdio.h>

int main (int argc, char const *argv[])
{
    char name[20];
    scanf("%[^\n]s",name);
    printf("%s\n", name);
    return 0;
}

يمكنك استخدام هذا

char name[20];
scanf("%20[^\n]", name);

أو هذا

void getText(char *message, char *variable, int size){
    printf("\n %s: ", message);
    fgets(variable, sizeof(char) * size, stdin);
    sscanf(variable, "%[^\n]", variable);
}

char name[20];
getText("Your name", name, 20);

التجريبي

لا تستخدم scanf() لقراءة السلاسل دون تحديد عرض حقل. يجب عليك أيضا التحقق من قيم الإرجاع للخطأ:

#include <stdio.h>

#define NAME_MAX    80
#define NAME_MAX_S "80"

int main(void)
{
    static char name[NAME_MAX + 1]; // + 1 because of null
    if(scanf("%" NAME_MAX_S "[^\n]", name) != 1)
    {
        fputs("io error or premature end of line\n", stderr);
        return 1;
    }

    printf("Hello %s. Nice to meet you.\n", name);
}

بدلا من ذلك، استخدم fgets():

#include <stdio.h>

#define NAME_MAX 80

int main(void)
{
    static char name[NAME_MAX + 2]; // + 2 because of newline and null
    if(!fgets(name, sizeof(name), stdin))
    {
        fputs("io error\n", stderr);
        return 1;
    }

    // don't print newline
    printf("Hello %.*s. Nice to meet you.\n", strlen(name) - 1, name);
}

يمكنك استعمال ال fgets() وظيفة لقراءة سلسلة أو استخدام scanf("%[^\n]s",name); لذلك سوف تنتهي قراءة السلسلة عند مواجهة شخصية نيولين.

getline()

الآن جزء من posix، لا شيء أقل.

كما أنه يعتني بمشكلة تخصيص المخزن المؤقت الذي طرحته في وقت سابق، على الرغم من أنك يجب أن تعتني به freeجي الذاكرة.

إذا كان شخص ما لا يزال يبحث، فأي ما كان يعمل بالنسبة لي - لقراءة طول التعسفي من السلسلة بما في ذلك المسافات.

بفضل العديد من الملصقات على شبكة الإنترنت لمشاركة هذا الحل البسيط والأنيق. إذا كان يعمل الائتمان يذهب إليهم ولكن أي أخطاء هي لي.

char *name;
scanf ("%m[^\n]s",&name);
printf ("%s\n",name);

يمكنك استخدام scanf لهذا الغرض مع خدعة صغيرة. في الواقع، يجب عليك السماح بإدخال المستخدم حتى يدخل المستخدم (\n). هذا سوف ينظر في كل شخصية، بما في ذلك الفضاء. وبعد هنا مثال:

int main()
{
  char string[100], c;
  int i;
  printf("Enter the string: ");
  scanf("%s", string);
  i = strlen(string);      // length of user input till first space
  do
  {
    scanf("%c", &c);
    string[i++] = c;       // reading characters after first space (including it)
  } while (c != '\n');     // until user hits Enter
  string[i - 1] = 0;       // string terminating
return 0;
}

كيف يعمل هذا؟ عندما يقوم المستخدم بإدخال الأحرف من الإدخال القياسي، سيتم تخزينها سلسلة متغير حتى المساحة الفارغة الأولى. بعد ذلك، ستبقى بقية الدخول في دفق الإدخال، وانتظر SCANF التالي. بعد ذلك، لدينا for حلقة التي تتقدم سحر من سحر المدخلات (حتى \n) وإقاداتهم إلى نهاية سلسلة متغير، وبالتالي تشكيل سلسلة كاملة مثل إدخال المستخدم من لوحة المفاتيح.

امل ان يساعد هذا احد!

بينما يجب أن لا تستخدم حقا scanf() لهذا النوع من الشيء، لأن هناك مكالمات أفضل بكثير مثل gets() أو getline(), ، يمكن إنجازه:

#include <stdio.h>

char* scan_line(char* buffer, int buffer_size);

char* scan_line(char* buffer, int buffer_size) {
   char* p = buffer;
   int count = 0;
   do {
       char c;
       scanf("%c", &c); // scan a single character
       // break on end of line, string terminating NUL, or end of file
       if (c == '\r' || c == '\n' || c == 0 || c == EOF) {
           *p = 0;
           break;
       }
       *p++ = c; // add the valid character into the buffer
   } while (count < buffer_size - 1);  // don't overrun the buffer
   // ensure the string is null terminated
   buffer[buffer_size - 1] = 0;
   return buffer;
}

#define MAX_SCAN_LENGTH 1024

int main()
{
   char s[MAX_SCAN_LENGTH];
   printf("Enter a string: ");
   scan_line(s, MAX_SCAN_LENGTH);
   printf("got: \"%s\"\n\n", s);
   return 0;
}
/*reading string which contains spaces*/
#include<stdio.h>
int main()
{
   char *c,*p;
   scanf("%[^\n]s",c);
   p=c;                /*since after reading then pointer points to another 
                       location iam using a second pointer to store the base 
                       address*/ 
   printf("%s",p);
   return 0;
 }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top