Tại sao giá trị trả về của scanf là 1 mà không phải giá trị nhập vào?

Lệnh scanf có giá trị trả về, giá trị trả về không phải giá trị em nhập:

Tuoi = scanf("%d", &Tuoi) # Không thể lấy được giá trị tuổi em muốn theo cách này

Cụ thể hàm scanf trả về như này:

scanf returns EOF if end of file (or an input error) occurs before any values are stored. If any values are stored, it returns the number of items stored

Em đọc thêm 2 link dưới đây để tìm hiểu thêm.

https://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr1/z2056339.htm

6 Likes

Tại sao?

printf(“Bạn %d tuổi.\n, Tuoi = scanf(”%d", &Tuoi));

Tại vì bị thiếu dấu "

printf(“Bạn %d tuổi.\n”, Tuoi = scanf("%d", &Tuoi));

5 Likes

có ạ! nhưng nó chỉ trả về kết quả là 1 cho dù ta có nhập số gì đi chăng nữa

à em lúc code nên đây chắc có thiếu sót. chứ code trên máy thì có cả bác ạ! cảm ơn bác chỉ lỗi sai cho em nhé

http://www.cplusplus.com/reference/cstdio/scanf/

Bạn gán (kiểu ngắn gọn) như thế là không được. Giá trị trả về là số lượng tham biến được đổ giá trị thành công. Bạn chỉ dùng 1 tham biến Tuoi nên giá trị trả về là 1. Có thể là 0 nếu giá trị không hợp lệ hoặc gặp EOF.

4 Likes

tớ đọc đc 1 đoạn code trong 1 quyển sách C phần lặp for cùng hàm in và hàm nhập, họ nói là : đa số các hàm có sẵn đều trả về 1 giá trị. nên tớ nghĩ ,nếu hàm printf trả về giá trị int số lượng ký tự(bao gồm cả ký tự ‘\n’ tính = 2)
vd :kt = printf(“name\n”);–> printf("%d,kt");thì giá trị kt trả về là 6 (bao gồm “name” và ‘\n’)
vì thế nên trong ví dụ lặp for họ viết như này :

while (scanf("%d %d,&x,&y) == 2 )
   {do something}

Thì theo cách hiểu của tớ,nếu lặp while kia chạy mà ta nhập thừa 1 tham số chương trình sẽ kết thúc. nên suy ra giống như hàm printf hàm scanf cũng sẽ trả về 1 giá trị kiểu int biểu diễn cho số lượng tham số ta nhồi vào hàm scanf đó.

1 Like

Hi there,

Đừng đoán nhé @luantran11490 :smile:
Cậu nên đọc manual của scanf để biết giá trị trả về của scanf là gì. @SITUVN.gcd có đề cập nó ở ngay comment này:

Hàm scanf sẽ trả về số lượng biến trong argument có thể gán được.
Vậy nên, code này:

while(scanf("%d %d", &x, &y) == 2)
{
  //do something
}

Hàm scanf có 2 biến có thể gán, vậy nên nó sẽ trả về:

  • 2 nếu như cả 2 biến x và y được gán giá trị.
    Ví dụ: nếu cậu nhập “1 2”, khi này x := 1, y := 2.
  • 1 nếu như hoặc chỉ x, hoặc chỉ y được gán giá trị.
    Ví dụ: cậu nhập “1 a”, ký tự ‘a’ không phải số nguyên như kỳ vọng “%d”, nên chỉ có biến x được gán bằng 1.
  • 0 nếu như cả 2 biến xy không được gán giá trị.
    Ví dụ: cậu nhập “a b”. Cả 2 ký tự này không phải số, nên chẳng có biến nào được gán cả.

Vậy nên, nếu cậu muốn phát hiện có bất cứ input nào bị nhập sai, cậu chỉ cần check scanf("%d %d", &x, &y) == 2 (true khi input đúng với cả 2 biến).

Hope it helps!

5 Likes

Thì ý của mình là nó trả về giá trị số lượng đối số (gồm số lượng đối số trong dấu " " ) cùng đối địa chỉ tương ứng đưa vào .và theo câu lệnh
While ( scanf(" %d %d",&x,&y) ==2 )
Thì cá nhân mình hiểu là nó ngầm trả giá trị =2 nếu ta nhập đúng 2 đối,nó sẽ ngầm trả giá trị 3,4… nếu nhập nhiều hơn 2 đối.còn hiện tại thì mình cũng k biết cách thức để in giá trị trả về của hàm scanf,nên cũng chỉ hiểu ngầm là như vậy. Nhưng nếu khác cách hiểu của bạn, thì bạn có thể giải thích giúp mình rằng nếu cái hàm scanf trên với 2 đối số nhập k trả về giá trị int(số lượng đối số khai trong hàm scanf) thì while lấy cơ sở nào để so sánh điều kiện ==2? Có chăng cách giải thích khác hợp lý hơn k ?

Tớ biết cậu mới học C, nên tớ khuyên cậu đừng dùng những thuật ngữ nghe phức tạp và nguy hiểm :smile: “Ngầm trả về”, “đối” không phải thuật ngữ đúng đâu cậu (và nó cũng không mang ý nghĩa gì).
Cậu cũng hoàn toàn có thể in giá trị trả về của scanf bằng printf :smile:

Tớ đã đề cập ở comment trước, cậu nên đọc document của hàm scanf để hiểu thêm (ở comment của @SITUVN.gcd, mà tớ đã quote lại ở comment trước). Document đã nói rất rõ ràng rồi :smile:
Cá nhân tớ đã giải thích thêm ví dụ cụ thể để cậu dễ hiểu hơn ở comment trước rồi đó :smile: Mà thậm chí, ở các comment trước nữa cũng đã giải thích rất rõ ràng, không có gì “ngầm hiểu” ở đây cả :smile:

5 Likes

Bởi vì những người làm ra nó muốn nó như vậy.
Em nên đọc tài liệu về nó để biết nó dùng như thế nào thay vì ngồi đoán rồi thắc mắc sao nó không như mình nghĩ.

5 Likes

bạn đang cố gán cho tớ cái mác nguy hiểm r,tớ mới học C,và các cmt của tớ đều là ý hiểu của tớ đc chia sẻ,ngay cả cái câu : “mình ngầm hiểu-tức là tự bản thân tớ ngầm hiểu ý của dòng code” . quay lại cái chủ đề , chốt lại ý của tớ là :“cái hàm scanf nó trả về 1 số nguyên tương ứng với số “đối số”(kèm theo những chữ &)”.Tớ để từ " đối số" trong ngoặc kép, vì theo bạn nói đó k phải là đối số.(cái này xin bạn chỉ dạy -vì tớ chỉ mới học C đc 1,2tháng trở lại đây).tại sao tớ kết luận vậy bởi theo sau đó tớ thấy 1 đoạn code lặp :

while( scanf("%d %d",&x,&y) ==2)
{do somthing}

–> Tớ thấy chương trình có dòng code trên chạy ok nên tớ suy ngược lại theo logic của tớ ra cái phần " chốt lại" ở trên của tớ như vậy. còn tớ sai, thì trc xin lỗi tất cả mọi người,sau mong bạn giải thích tại đây giúp tớ câu hỏi : “làm sao cái vòng lặp kia nó có thể chạy đc ? dựa vào cơ sở nào để máy tính chạy cái while đó nếu nó k có cái gì để so sánh?”.Cảm ơn bạn
còn đây là code tớ lượm lặt đc trên mạng trả về giá trị của hàm nhập scanf với lần lượt các đối số đầu vào 1,2,3.

int main()

{
          char a[100], b[100], c[100];
                 // scanf() 1 đầu vào
            printf("\n First scanf() returns : %d",scanf("%s", a));
                 // scanf() 2 đầu vào
            printf("\n Second scanf() returns : %d",scanf("%s%s", a, b));
                             // scanf() 3 đầu vào
           printf("\n Third scanf() returns : %d",scanf("%s%s%s", a, b, c));
}

kết quả nhập :

First scanf() returns : 1
 Second scanf() returns : 2
 Third scanf() returns : 3

Kèm theo câu : "scanf(): It returns total number of input Scanned succesfully… "

1 Like

bác có thể giải thích giúp e tại sao chương trình này nó lại chạy k ạ ?
while(scanf(%d %d ,&x ,&y) ==2 )
{do blah blah}
e mới học C , tấm chiếu mới ,nên xin đc khai sáng , E cảm ơn

Đầu tiên em có thể xem các cú pháp liên quan đến vụ scanf ở đây :
https://docs.microsoft.com/vi-vn/cpp/c-runtime-library/reference/scanf-scanf-l-wscanf-wscanf-l?view=msvc-160

Trong link trên ở phần Syntax (cú pháp) sẽ thấy hàm scanf nó có cú pháp như sau:

  • Tham số đầu tiên (format) dạng const char*. Nó là một chuỗi chứa định dạng các dữ liệu cần scan. Và chuỗi thì phải bao trong dấu nháy kép. Đối chiếu code trên thì thấy thiếu dấu nháy kép.
  • Các tham số tiếp theo là con trỏ tới từng phần tử cần scan tương ứng với format. Lấy con trỏ thì phải có & nếu biến không phải con trỏ.
    Hàm trả về số dữ liệu được scan thành công.

Theo như trên thì hàm scan sẽ viết như sau:

scanf("%d %d", &x, &y)

Hàm này thành công thì trả về 2 vì có 2 biến cần được scan.
Để kiểm tra có thành công hay không thì so sánh kết quả với 2.

3 Likes

Thế thì đúng như ý e đã cmt ở trên r bác,bởi vì chả có lý do gì cái hàm while đó chạy ok mà em k thể suy luận ngược lại rằng cái hàm "scanf " kia nó k trả về 1 giá trị nguyên trùng với số đối số cùng với cái chữ “&” (trừ mảng[]) đc nhét vào hàm cả.Thêm nữa là bạn trên cmt nói rằng nó k phải là đối số kiểu tham chiếu, vậy e đang thắc mắc rằng ,nếu hàm có các thành phần ở bên trong dấu ( ) thì các thành phần bên trong đó đc gọi là gì?

Mình phải đọc đi đọc lại comment của bạn 3 lần mới hiểu được rõ được bạn đang muốn nói gì :sweat:

Cứ cho là bạn muốn hiểu theo kiểu của bạn đi, vậy bạn giải thích sao về ví dụ này

#include <stdio.h>

int main(void) {
	int a = -1, b = -1; // initialization
	int result = scanf("%d %d", &a, &b);
	printf("%d %d %d\n", result, a, b);
}

khi nhập vào 1 abc?

5 Likes

:smile:

Nào nào,
Tớ không ở đây để bới lông tìm vết, hay chỉ ra sự dốt nát của ai ở đây cả. Comment dưới đây chỉ cố gắng tổng hợp lại mọi thứ, cùng với một số lời khuyên tớ nghĩ là sẽ hữu ích cho sự nghiệp của cậu sau này.
Vì cuộc nói chuyện đang đi lệch hướng, để tớ quay lại từ comment đầu tiên của cậu nhé!

Comment dưới đây của cậu là lý do tớ đã reply để giúp cậu hiểu đúng này:

Thì theo cách hiểu của tớ,nếu lặp while kia chạy mà ta nhập thừa 1 tham số chương trình sẽ kết thúc. nên suy ra giống như hàm printf hàm scanf cũng sẽ trả về 1 giá trị kiểu int biểu diễn cho số lượng tham số ta nhồi vào hàm scanf đó.

Chữ in đậm kể trên là false assumption, và là lý do chính tớ reply cậu. Khi cậu nhập thừa 1 tham số, scanf trong ví dụ của cậu, vẫn sẽ trả về tối đa là 2 thôi.
Tớ sẽ không đi chi tiết giải thích tại sao nó trả về 2 khi cậu nhập 3 giá trị, cậu sẽ biết trong quá trình học.
Ở comment trả lời comment đó, tớ đã đưa ra ví dụ cho cậu, để thấy chỉ có 3 giá trị scanf sẽ trả về, trong 3 TH khác nhau.

Cậu mắc 2 sai lầm ở comment kể trên:

  1. Đưa ra giả thiết, nhưng không tự chứng minh.
  2. Không đọc manual, và đưa ra quan điểm dựa trên việc “đoán”.

Cả 2 sai lầm trên không chỉ có ở newbie như cậu, mà kể cả các kỹ sư (tồi) nhiều năm kinh nghiệm (không chỉ ở VN đâu). Đó là thứ tớ muốn cậu cải thiện.

Ở comment tiếp theo, cậu tiếp tục đi vào vết xe đổ đó.

Thì cá nhân mình hiểu là nó ngầm trả giá trị =2 nếu ta nhập đúng 2 đối, nó sẽ ngầm trả giá trị 3,4… nếu nhập nhiều hơn 2 đối

Ở đây cậu có các sai lầm:

  • Dùng thuật ngữ sai.
    Tớ biết kiểu newbie như cậu, cậu thường cố gắng sử dụng thuật ngữ riêng của bản thân, thay vì sử dụng thuật ngữ chung.
    Như tớ đã lịch sự chỉ cho cậu, cậu không nên dùng nó. “Ngầm trả về” không có ý nghĩa gì (trả về là trả về, sao lại “ngầm”? :smile: Dù tớ hiểu, cậu muốn nói cậu “ngầm hiểu”, nhưng đó là do tớ thông minh nên hiểu ý cậu, chứ không phải do cậu diễn đạt đúng), “đối” cũng là từ riêng của cậu cho từ “đối số”.
    Cậu sẽ gặp rắc rối về việc diễn đạt bản thân trong môi trường chuyên nghiệp sau này, nếu cậu vẫn dùng những thuật ngữ như vậy. Dùng từ đơn giản và chính xác là lời khuyên của tớ dành cho cậu.
  • Vẫn là false asumption “trả về 3 nếu nhập 3 giá trị”. Tớ đã nghĩ cậu chưa đọc kỹ các comment trước, nên đã khuyên cậu đọc kỹ.

Ở comment dưới đây:

bạn có thể giải thích giúp mình rằng nếu cái hàm scanf trên với 2 đối số nhập k trả về giá trị int (số lượng đối số khai trong hàm scanf) thì while lấy cơ sở nào để so sánh điều kiện ==2? Có chăng cách giải thích khác hợp lý hơn k ?

Đây là sai lầm của cậu:

  • Tớ e là, cậu có khả năng đọc hiểu vô cùng tồi tệ :smile:
    Cậu có thể thấy, từ manual, tới các ví dụ tớ đưa ra, đều chỉ ra scanf sẽ trả về 1 số nguyên. Liệu cậu đã thực sự đọc bất cứ comment nào ở đây, hay cậu đang cố biến bản thân thành 1 kẻ bảo thủ cho rằng mình đúng, bằng cách đưa ra false statement về người khác? :smile:
    Nếu cậu không chịu đọc kỹ các comment khác + manual, như tớ đã lịch sự chỉ ra ở comment trước, cuộc nói chuyện của chúng ta sẽ kết thúc, vì cậu không thèm lắng nghe người khác.
  • Đây cũng là một điều tớ cần lưu ý cậu, cậu cần học cách lắng nghe. Một kỹ sư vừa lười đọc doc, vừa thích đưa ra các giả thiết nhưng không chứng minh, vừa dùng thuật ngữ mà chỉ mình anh ta hiểu, lại không biết lắng nghe, là kiểu kỹ sư mà không một tổ chức nào muốn làm việc cùng.

Ở comment cuối cậu reply tớ, cậu đã hiểu được cách in ra giá trị scanf rồi.
Cơ mà ở dòng này:

Tớ để từ " đối số" trong ngoặc kép, vì theo bạn nói đó k phải là đối số.

Và:

Thêm nữa là bạn trên cmt nói rằng nó k phải là đối số kiểu tham chiếu

Tớ nghĩ cậu đang lộn việc nói chuyện với ai đó rồi :smile: Vì ở ngay comment đầu tiên của tớ có nói:

Hàm scanf sẽ trả về số lượng biến trong argument có thể gán được.

Cậu đang cố chứng minh tớ sai cái gì thế? :smile: Nếu cậu đang nói chuyện với người khác, đừng reply comment của tớ một cách dở hơi vậy nha :smile:

Giờ, cậu có thể thử trả lời @noname00 câu hỏi ở trên xem.

Hi vọng lần này cậu hiểu.

7 Likes

Bạn nói tớ dùng thuật ngữ,vậy bạn đang dùng cái gì để biện luận thế ? Argument là cái gì ? Tớ trích lại câu của bạn nhé

ok để tớ nói ý hiểu của tớ như này nhé : trong tiếng việt k có từ argument,và nếu tra từ điển thì nó dịch là “đối số”.định nghĩa đối số : là những gì thực tế ta mang vào khi gọi tới 1 hàm,đối số hay cái từ argumentmà bạn coi nó k phải là thuật ngữ có 3 loại : loại biến thông thường, con trỏ và tham chiếu( tham chiếu chính là địa chỉ kèm theo cái ký tự “&”).Và tớ chắc chắn 1 điều là ở hàm scanf k dùng biến kiểu thường,1 là con trỏ 2 là địa chỉ.Vì vậy cái cách tớ nói “hàm scanf ngầm trả về 1 giá trị số nguyên = số lượng đối số (hoặc số ký tự “&”-ngoại trừ mảng k có dấu “&”) có trong hàm” chả có gì k hợp lý cả, chắc nên thay thuật ngữ đối số = thuật ngữ “argument”,nhưng mà do tớ quen từ đối số với **tham số ** hay thuật ngữ C gọi là parameter học ở toán lớp 9 r nên cách nói khác của bạn vậy. suy cho cùng thì tớ nói tiếng việt còn bạn nói tiếng anh,k hiểu nhau cũng là bt thôi :smiley:.bạn còn k hiểu tớ đang nói gì thì làm sao mà nói chuyện đc. Nào ,lại từ đầu nhé :

while (scanf("%d%d,&x,&y) ==2)
{do st}

Thực sự tớ vẫn k hiểu ý bạn là gì?bạn khai sáng giúp tớ vài dòng code tường minh thay vì để tớ phải ngầm hiểu mấy cái dòng trong lặp while đấy với.tớ cũng k rõ bạn hiểu cái tường minh và ngầm định như nào,nhưng cá nhân tớ hiểu tường minh là khi nhập cái dòng “scanf(…)” kia ra,sau khi nhập xong số argument đúng và đủ kia,nhấn enter, hàm sẽ in ra thêm 1 dòng trả về số lượng argument đã nhập,chứ k phải dấu nhẹm nó đi và để tớ phải tư duy theo cái từ “ngầm hiểu”.vì thế,ở trong cái code while tớ nói là tớ phải ngầm hiểu chả có gì là sai cả,còn bạn nói tớ dùng thuật ngữ,what? liên quan? Và cái kết luận tớ đưa ra ở cmt của tớ là : nhập bao nhiêu cái dấu “&” thì trả ra bấy nhiêu cái,nhập 2 cái thì nhập nhiều hơn cũng chỉ lấy 2 cái đầu ĐÚNG VÀ ĐỦ-> rồi tớ suy rộng ra thì hàm scanf trả về 1 số nguyên là số lượng “argument” (như cách bạn nói) hay đối số (như cách tớ nói) có trong hàm. Bạn lại bảo đừng suy luận bừa :smiley:,ct chạy đúng ý định<=>chứng tỏ code while đúng=> chả có lý do gì mà cái đk trong cái ngoặc của while k đúng cả,từ cái đk đúng đó suy rộng đc 1 cái vấn đề khác liên quan(chính là cái vấn đề mà tớ nêu ra),như vậy là suy luận bừa ?Chính xác là như vậy,nhưng bạn lại kéo xa quá vấn đề,lỗi cũng do tớ viết nhập nhèm.Sau cùng,tớ xin bày tỏ rằng tớ k có ý định làm 1 kỹ sư gì gì đó,tớ chỉ là ng hay tò mò về các vấn đề liên quan đến cái máy tính hoạt động bt,nên tớ tìm hiểu C ,cũng mới đc 1,2 tháng dịch trở lại đây.tiện nói về ng VN,tớ cũng thấy k ít ông bảo thủ,trong đó có tớ,cũng k ít ông lúc nào cũng đem cái chủ nghĩa kinh nghiệm theo bên mình,cũng tốt nhưng nhiều quá thì lại k hay.cảm ơn bạn đã đọc và góp ý cho tớ.

Mình vẫn đang đợi câu trả lời của bạn @luantran11490. Thêm 1 câu hỏi khác, nếu bạn cho rằng hàm scanf ngầm trả về 1 cái gì đó, vậy hàm scanf trả về giá trị gì 1 cách lộ liễu?

2 Likes

lộ liễu? Viết thêm code thì là ngầm hả bạn?đấy là bạn muốn nó tường minh ra r chứ k phải là ngầm nữa.đơn giản thôi,bạn gọi độc cái hàm scanf ra ,xong gõ giá trị theo số lượng vào,như ví dụ của bạn thì 2 đối số a,b. Xong enter xem nó có in tường minh ra thêm cái số lượng biến bạn đã nhập k. Nếu in ra thì đó mới gọi là tường minh,còn bạn dùng 1 biến khác để gán cho hàm sau đó in biến này ra thì là do bạn tác động r,chứ k phải bản thân hàm trả về như vậy . Tương tự như hàm printf,cũng làm gì trả về số ký tự nhập,vẫn phải gán biến r in cái biến đấy ra.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?