كيف تسمح بإدخال المسافات باستخدام SCANF؟
-
12-09-2019 - |
سؤال
باستخدام التعليمات البرمجية التالية:
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);
لذلك سوف تنتهي قراءة السلسلة عند مواجهة شخصية نيولين.
الآن جزء من 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;
}