לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תכנות ובניית אתרים
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 03-03-2012, 14:04
צלמית המשתמש של SkyRaider
  SkyRaider SkyRaider אינו מחובר  
 
חבר מתאריך: 08.02.06
הודעות: 941
שרשור מחרוזות strcat

נתון הקוד:
קוד:
#include <stdio.h> #include <conio.h> #include <string.h> // here starts the functions int main() { char s1[15]; char s2[15]; char s3[15]; printf ("enter 3 strings: "); fgets(s1, 15, stdin); fgets(s2, 15, stdin); fgets(s3, 15, stdin); strcat( s1, s2); strcat( s1, s3); printf ("%s ", s1); getch(); return 0; }


הוא אמור לקבל קלט של 3 מחרוזות מהמשתמש ולהדפיס , לדוגמא:
קלט מהמשתמש:
hello
world
again
פלט:
hello world again
משום מה התוכנית מדפיסה לי
hello
world
again

איפה טעיתי? הקוד הגיוני לא? קודם משרשר את 1 ו2 ואז את התוצר שלהם עם 3?

עכשיו מספר שאלות להבנה יותר מעמיקה:

קוד:
strcat( s1, s2, s3);


1. אני מבין שאת הקוד הזה לא ניתן להכניס כיוון שהמערכת לא מכירה את זה? (המטרה בקוד הזה בעצם לשרשר מחרוזת אחר מחרוזת.

2. קוד אחר:
קוד:
char input[256]; int i; fgets( input, 256, stdin ); for ( i = 0; i < 256; i++ ) { if ( input[i] == '\n' ) { input[i] = '\0'; break; } }

אמור לתת שורה חדשה כל פעם שהמשתמש מכניס \n אבל זה לא עובד אלא מדפיס את \n כחלק מהסטרינג, מדוע?

3. בתרגיל אחר שעשיתי, נתבקשתי לכתוב תוכנית שמבקשת את שם המשתמש, ומדפיסה הודעת שלום, אז כתבתי תוכנית שמקבלת דרך fgets אבל לצערי, הפלט יצא רחוק מהרצוי, לדוגמא:
מהלך התוכנית:
פלט: "הכנס שמך: "
קלט: משה.
פלט: "שלום משה
, מה שלומך?"
התוכנית הייתה יורדת שורה לאחר המחרוזת ("משה"), מדוע?
ומה שמצחיק זה, שscanf דווקא פתר את הבעיה, למרות הבעייתיות שלו.
נאלצתי לשים scanf במקום fgets כי כל פעם שהייתי מדפיס

4. בקוד הראשון אני חוזר על הרבה ביטויים, מה הדרך לייעל את הקוד כמובן בהתאם לרמתי ולא מתקדם יותר.

5. כשמבקשים מהמשתמש להקליד 3 מחרוזות, אחת הדרכים היא ליצור 3 מחרוזות נפרדות. האם ניתן ליצור בדרך אחרת מחרוזת אחת דו מימדית 3 על *מס' תווים? האם זה נחשב ל-3 מחרוזות נפרדות?

כל טיפ איך להיזהר לא לעבור את הגבולות של המחרוזות בכל הפונקציות שלהן יתקבל בברכה, עדיין לא סגור על הנושא הזה וההסברים שאני קורא לא מבהירים באופן חד וחלק.
בתודה מראש!
_____________________________________
Bad Spellers Unite!


נערך לאחרונה ע"י SkyRaider בתאריך 03-03-2012 בשעה 14:08.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #5  
ישן 03-03-2012, 16:53
צלמית המשתמש של SkyRaider
  SkyRaider SkyRaider אינו מחובר  
 
חבר מתאריך: 08.02.06
הודעות: 941
בתגובה להודעה מספר 4 שנכתבה על ידי CM0S שמתחילה ב "איך ניסית להסיר? נראה לי..."

קוד:
#include <stdio.h> #include <conio.h> #include <string.h> // here starts the functions int main() { char s1[15]; char s2[15]; char s3[15]; printf ("enter 3 strings: "); fgets(s1, 15, stdin); fgets(s2, 15, stdin); fgets(s3, 15, stdin); strcat( s1, s2); strcat( s1, s3); int i; for ( i = 0; i < 15; i++ ) { if ( s1[i] == '\n' ) { s1[i] = '\0'; break; } } printf ("%s ", s1); getch(); return 0; }


יכול להיות שטעיתי אבל בלולאה התייחסתי רק למחרוזת הראשונה, כי מבחינתי כבר שירשרתי בה את שתי המחרוזות האחרות, יכול להיות שהתפיסה שלי שגויה?


קוד:
char input[256]; int i; int x=1; printf ("enter a string, to end press 'p'\n"); fgets( input, 256, stdin ); while (x!='p'){ printf ("to end press 'p'.\n"); scanf("%d", &x); for ( i = 0; i < 256; i++ ) { if ( input[i] == '\n' ) { input[i] = '\0'; break; } } }


דוגמא לאחת הנסיונות שלי לפתור את הבעיה.
כאן כמו שאתה רואה ניסיתי להשתמש בwhile .
ניסיתי גם בdo..while.

שיחקתי עם שתי השורות של:
קוד:
printf ("to end press 'p'.\n"); scanf("%d", &x);


ניסיתי למקם אותם בכל מני מקומות בתוך לולאת הwhile וגם בfor אבל לא הצלחתי... לצערי.

עכשיו שאלה כללית,

זה סביר שיהיו לי כלכך הרבה בעיות כאלה ואחרות בתור מתחיל בתחום?
אציין גם שאני מנסה ללמוד את c דרך שני מקורות לימוד עצמיים, וויקיספר (שם אני שואב אקסטרה מידע ומנסה לפתור את התרגילים שם, כי לא הצלחתי למצוא בשום מקום אחר תרגילים שעובדים לפי רמות עם פתרונות לבדיקת תשובה. והאתר השני שאני לומד ממנו הוא אתר בשם cprogramming שבעיקרון הבחור שם כתב הסבר על c וcpp והשקיע יותר בשני..
כל עזרה בנושא תוערך מאוד.
_____________________________________
Bad Spellers Unite!

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #6  
ישן 03-03-2012, 17:14
צלמית המשתמש של fritz2
  fritz2 fritz2 אינו מחובר  
 
חבר מתאריך: 28.01.07
הודעות: 912
בתגובה להודעה מספר 5 שנכתבה על ידי SkyRaider שמתחילה ב "[CODE]#include..."

עוד בעיה, היא שהקצת רק 15 תווים למחרוזת, ואתה מנסה לדחוס יותר תווים (אל תשכח שגם רווח, גם שורה חדשה, וגם סיום מחרוזת הם תווים).
נסה דרך פשוטה יותר עם
קוד:
scanf("%s", s1)

והגדל את אורך המחרוזת הסופית לבערך 32 תווים רק ליתר ביטחון.
כדי לדבג בצע הדפסה אחרי כל פעולה, וממש תרשום לעצמך מה ביצעת
קוד:
printf("used <strcat> on s1 and s2, the result is %s\n", s1)

למשל.

וכן, סי, ובעיקר סטרינגים שהם לא דאטה טייפ שמובנה בשפה, הם מקור לבעיות.
גם באקדמיה (שם למדתי את השפה) מתקשים בדיוק בנושא הזה, כי סטרינג זה כבר עולם של פוינטרים ומערכים (הפונקציה strcat למשל, מחזירה פוינטר לchar).

אלו דקויות קטנות, אל תתייאש.
_____________________________________
נכון אתם אנשים כשרים, אך לא לזאת הייתה כוונתי. רציתי שתהיו כחיות הנוהמות ביער לילות שלמים.

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #7  
ישן 03-03-2012, 17:28
צלמית המשתמש של SkyRaider
  SkyRaider SkyRaider אינו מחובר  
 
חבר מתאריך: 08.02.06
הודעות: 941
בתגובה להודעה מספר 6 שנכתבה על ידי fritz2 שמתחילה ב "עוד בעיה, היא שהקצת רק 15..."

ציטוט:
במקור נכתב על ידי fritz2
עוד בעיה, היא שהקצת רק 15 תווים למחרוזת, ואתה מנסה לדחוס יותר תווים (אל תשכח שגם רווח, גם שורה חדשה, וגם סיום מחרוזת הם תווים).
נסה דרך פשוטה יותר עם
קוד:
scanf("%s", s1)

צודק אבל קראתי שיש בעייתיות עם scanf בכל הנוגע למחרוזות והרבה יותר בטוח להשתמש בfgets גם בגלל שמצויין שם גודל המחרוזת.

וצודק הייתה לי שם טעות וגלשתי מעבר למוקצב, אילו בעיות לדוגמא זה יוצר בתוכנה?

על כל פנים, גם כשאני לא גולש מעבר למוקצה, (15) התוכנה עדיין לא עובדת, יש דרך לגרום לה לעבוד גם עם מה שעשיתי?

והגדל את אורך המחרוזת הסופית לבערך 32 תווים רק ליתר ביטחון.
כדי לדבג בצע הדפסה אחרי כל פעולה, וממש תרשום לעצמך מה ביצעת
קוד:
printf("used <strcat> on s1 and s2, the result is %s\n", s1)

למשל.

וכן, סי, ובעיקר סטרינגים שהם לא דאטה טייפ שמובנה בשפה, הם מקור לבעיות.
גם באקדמיה (שם למדתי את השפה) מתקשים בדיוק בנושא הזה, כי סטרינג זה כבר עולם של פוינטרים ומערכים (הפונקציה strcat למשל, מחזירה פוינטר לchar).

אלו דקויות קטנות, אל תתייאש.


לא מתייאש.
פשוט רוצה ללמוד בצורה טובה את החומר ולהצליח בבעיות, אני פשוט חושב שמקור החומר והתרגילים שלי שגויים, יש הצעות לדברים אחרים? ועברתי על לנקיית הפורום ובגוגל.
לא אכפת לי שיהיה באנגלית אבל לא טכני כמו מדי כמו המדריך של sun לjava.. אלא יותר user friendly
_____________________________________
Bad Spellers Unite!

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #9  
ישן 03-03-2012, 21:15
צלמית המשתמש של SkyRaider
  SkyRaider SkyRaider אינו מחובר  
 
חבר מתאריך: 08.02.06
הודעות: 941
בתגובה להודעה מספר 8 שנכתבה על ידי fritz2 שמתחילה ב "שתי הפונקציות שקולות ברגע..."

ציטוט:
במקור נכתב על ידי fritz2
שתי הפונקציות שקולות ברגע שאתה מקבל קלט מה stdin.
אם הסטרינג נקלט כמו שצריך, אז scanf תחזיר אינטג'ר "1".

אני מתאר לעצמי שכבר קראת את זה, אבל הדוגמאות כאן מצויינות:
http://www.cprogramming.com/tutorial/c/lesson9.html

נסה לקמפל ככה:
קוד:
gcc -Wall <filename.c>
(בהנחה שאתה משתמש בשרת יוניקס כלשהו), וזה ידפיס לך את כל האזהרות מלבד השגיאות.


הSTDIN זה בשגרה או שאני צריך לקרוא לו כמו בFGETS בהנחה שאני מקבל קלט בSCANF?
אם הסטרינג נקלט כמו שצריך. עולה לי שאלה, איך בדיוק FGETS שולט בכמה תווים נקראים בזיכרון? האם ניתן לראות את זה כשאני מדפיס, ובעצם זה מדפיס בדיוק את הגודל שנתבקש בהכרזה?
האם זה אומר שSCANF היה מדפיס לי את כל התווים שהכנסתי ללא קשר לגודל המחרוזת הנתונה?

משתמש לא דווקא יכניס את הסטרינג כמו שצריך, לכן עדיף FGETS, לפחות זה מה שטחן לי המדריך שהצעת בלינק.

אגב הקוד שרשמת, gcc - wall מה זה אומר? זה קשור ללינוקס?

מצטער על החוסר ידע המובהק...
_____________________________________
Bad Spellers Unite!

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #10  
ישן 03-03-2012, 18:33
  The_Equivocator The_Equivocator אינו מחובר  
 
חבר מתאריך: 11.02.04
הודעות: 16,543
בתגובה להודעה מספר 5 שנכתבה על ידי SkyRaider שמתחילה ב "[CODE]#include..."

א)ברמת העיקרון, מתחיל לא אמור להתעסק עם מחרוזות.
ב)לפני שמשתמשים בספריה מוכנה של סטרינגים, על אחד שהוא מתחיל, ואין לו מושג בתכנות, ובניהול זיכרון בשפת C עליו קודם כל לממש פונקציות משלו לעבודה עם מערכים של מחרוזות, רק אחר כך, אחד יכול להרשות לעצמו להשתמש בספריות מוכנות. (כך זה שלומדים C\C++).

נחזור לסעיף הראשון, אתה לא יודע לעשות רקורסיות בסיסיות, פונקציות פשוטות מבלי לעשות טעיות סינטקטיות, ולוגיות, למה אתה חש צורך לקפוץ בכלל לספריות של מחרוזות?!
אתה בכלל מבין מה זה "מחרוזת", ז"א, איך בשפת C, מיוצגת מחרוזת?
ציטוט:
כל טיפ איך להיזהר לא לעבור את הגבולות של המחרוזות בכל הפונקציות שלהן יתקבל בברכה, עדיין לא סגור על הנושא הזה וההסברים שאני קורא לא מבהירים באופן חד וחלק.
בתודה מראש!


אין שום פתרון קסם, הכל באחריותך בתור מתכנת בשפות הללו.
כאן בדיוק בדברים הללו טמונים היתרונות והחסרונות של שני השפות הללו.(כגון C\C++).
מהירות\ מול בטיחות- שאלת מה יכולים לעשות חריגות בזיכרון לתוכנית? הכל, ממתן תשובות שגויות, קריסת תוכנית\ ניצול באג בכדי לפרוץ למערכת שמריצה את התוכנית, ע"י ניצול של באפר-אובר פלו.

נערך לאחרונה ע"י The_Equivocator בתאריך 03-03-2012 בשעה 18:41.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #13  
ישן 03-03-2012, 21:30
צלמית המשתמש של SkyRaider
  SkyRaider SkyRaider אינו מחובר  
 
חבר מתאריך: 08.02.06
הודעות: 941
בתגובה להודעה מספר 12 שנכתבה על ידי fritz2 שמתחילה ב "לא מדוייק. [CODE] char *str1..."

המחרוזת הראשונה שרשמת היא בעצם מצביע למחרוזת str1 והזנת את הערך שלה להיות "..."(מה שכתוב). לא? כי כשאתה כותב למצביע, אתה בעצם כותב ישירות לכתובת הזיכרון של מה שמוצבע? בעצם יכול לשנות תוכן. כי עם מצביע אתה יכול:
1. לראות כתובת בזיכרון של כל דבר.
2. להכניס ערך.
3. מקווה שאני לא מפשל יותר מדי.. מקסימום אצור מצביע לשם משתמש אחר ואף אחד לא יידע שזה אני


באמת שאת פונקציית MALLOC לא הצלחתי להבין, בעיקר מכך שהתוכנית במדריך גם בשיעורים קודמים לא רצה.. (על MALLOC בלבד.)

עדיין מנסה להבין:
a[i] = i[a]
הסבר יוערך מאוד.

מערך בשם a שיש לו כמות של i ערכים?
ואז מערך בשם i עם כמות ערכים של a?
מה ההגיון פה? אפשרי בכלל? ומה מתקבל מזה?
_____________________________________
Bad Spellers Unite!

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #14  
ישן 03-03-2012, 22:19
צלמית המשתמש של fritz2
  fritz2 fritz2 אינו מחובר  
 
חבר מתאריך: 28.01.07
הודעות: 912
בתגובה להודעה מספר 13 שנכתבה על ידי SkyRaider שמתחילה ב "המחרוזת הראשונה שרשמת היא..."

המשתנה הראשון שהגדרתי הוא מסוג מצביע ל-char, והוא מצביע לכתובת בה מאוחסן התו הראשון.
דוגמאות קוד לגישה:
קוד:
char *str1 = "abc"; printf("%s %s", str1, str1 +1); Output: abc bc


שמת לב מה קרה? כשאמרתי לתוכנית להדפיס את str +1 המצביע קודם באחד, ואז זה החזיר את ערך המחרוזת עד הסוף.
כדי להדגיש עוד קצת:
קוד:
printf(%c %c", "abc"[1], *("abc" + 2)); Output: b c


זה כבר לשחק עם מצביעים ולעשות מה שנקרא דה-רפרנס, וזה חומר יחסית מתקדם.

כדי להגדיר מערך של אותיות (סטרינג) שתי ההגדרות הבאות שקולות:
קוד:
char s[] = {'a', 'b', 'c', '\0'}; char s[] = "abc";


ולגבי השאלה האחרונה שלך, אפשר לרוץ על מערכים בהרבה צורות.
נגיד על מערך של אינטג'רים אני יכול לרוץ כך לצורך הדפסה::
קוד:
for (i = 0; i < SIZE; i++) printf ("%d ", a[i]); for (i = 0; i < SIZE; i++) printf ("%d ", *(a + i)); int *pa = a; for (i = 0; i < SIZE; i++) printf ("%d ", *(pa++)); for (i = 0; i < SIZE; i++) printf ("%d ", i[a]);


i הוא משתנה שרץ בלולאה להדפסת המערך.
ארבעת הצורות האלו ידפיסו את כל הערכים במערך a למסך.
הראשונה והאחרונה שקולות למרות שהחלפתי את סדר המשתנים.
למה?
כי
קוד:
a[i] = *(a + i) i[a] = *(i + a)

ומכאן נובע השוויון.
_____________________________________
נכון אתם אנשים כשרים, אך לא לזאת הייתה כוונתי. רציתי שתהיו כחיות הנוהמות ביער לילות שלמים.


נערך לאחרונה ע"י fritz2 בתאריך 03-03-2012 בשעה 22:31.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #24  
ישן 04-03-2012, 15:12
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 23 שנכתבה על ידי fritz2 שמתחילה ב "עובד יופי, שכחת להוסיף כנראה..."

צר לי להגיד זאת, אך באופן מפתיע, אדון אקוויבוקטור צודק.
אצלך, במקרה, הקוד הזה עבד. לפי התקן, התוצאות הן undefined.
הנה, תראה מה קורה כאן: http://ideone.com/yoolD

הסיבה היא ש-string literals נשמרים (אולי) באזור סטטי של הזיכרון, שעשוי להיות read-only.
דוגמה נפוצה היא שקבועים כאלה נשמרים ב-‎.rodata (כלומר, read-only data), משתנים גלובאליים נשמרים ב-‎.data, והקוד נשמר ב-‎.code או ‎.text - כל אלה שמות של section-ים (או סגמנטים) ב-executable.

המשתנה s1 מצביע לזיכרון שהוא לקריאה בלבד, וכך גם s2. ברגע ש-strcpy מנסה לכתוב לזיכרון הזה, התוכנה עפה (על SIGSEGV בלינוקס, כמו בלינק, או על AV בווינדוס).

מצוין גם פה: http://c-faq.com/decl/strlitinit.html
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

אמר פסטן: שניהם גרועים, אבל עדיף להיות טיפש מאשר שקרן.
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #26  
ישן 04-03-2012, 16:33
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 25 שנכתבה על ידי fritz2 שמתחילה ב "אני מבין ומקבל את מה..."

זה אפילו יותר גרוע מתלוי-מכונה. הנה החלק הרלבנטי מהתקן:
http://stackoverflow.com/questions/...6143043#6143043

המשפט החשוב הוא:
The effect of attempting to modify a string literal is undefined.
ב-C יש מספר סוגים של התנהגות-שלא-מוגדרת-לגמרי. ההסברים עליהם כאן:
http://c-faq.com/ansi/undef.html

כשאומרים "תלוי-מכונה", הכוונה לדוגמה לגודל של unsigned long int. האם זה 32 ביט? האם זה 64 ביט? זה תלוי-מכונה, אבל זה צריך להיות מתועד על ידי הקומפיילר שבו אתה משתמש, וכל עוד אתה עובד במסגרת שהוגדרה לך, הכל יהיה בסדר.

במקרה שלנו, טכנית, זה תלוי מכונה, מערכת הפעלה, קומפיילר, סביבת ריצה (אולי אתה משתמש ב-glibc, אולי ב-dietlibc, אולי כתבת בעצמך...), ובעוד המון גורמים בלתי-ידועים. אבל יכול גם להיות שהקוד הזה לא יתקמפל בכלל. יכול להיות שהוא יום אחד יתקמפל ויום אחד לא. יכול להיות שהוא יתקמפל, ומה שהקוד יעשה זה לפרמט לך את ההרדיסק, ויכול להיות שהוא ישגר טילים גרעיניים לעבר בייג'ין. undefined אומר שיכול לקרות כל דבר בלי שום הגבלות.

בקשר לשרת שלכם, בקישור הקודם שהבאת היה כתוב:
Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string literals to be formally treated as arrays of const char (for better error catching).
החצי הראשון של המשפט זה מה שחשוב. יכול להיות שהקומפיילר שלכם הוגדר לפרגן לכם, ויכול להיות שבמקרה זה עבד לך עד היום...
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

אמר פסטן: שניהם גרועים, אבל עדיף להיות טיפש מאשר שקרן.
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #27  
ישן 04-03-2012, 16:41
צלמית המשתמש של fritz2
  fritz2 fritz2 אינו מחובר  
 
חבר מתאריך: 28.01.07
הודעות: 912
בתגובה להודעה מספר 26 שנכתבה על ידי פסטן שמתחילה ב "זה אפילו יותר גרוע..."

הבנתי, תודה על ההסבר המפורט.

אם כך מה הדרך לטפל בהעתקת מחרוזות (כאלו שהוגדרו כפוינטר לצ'אר) וכיצד כן יש להשתמש ב strcpy?
הרי היא מקבלת שני משתנים, האחד פוינטר לצ'אר אליו אמורים להעתיק את המחרוזת הבאה, והשני הוא המחרוזת להעתקה, קבוע שהוא פוינטר לצ'אר.
אם אנחנו מסכימים, אז הרי שהפונקציה הזו לא יכולה לעבוד בשום תנאי.
ואם נמשיך בדוגמא, ונניח שאפשר להעביר לפונקציה מערכים של צ'אר, אז אנחנו נאלצים להסכים שפוינטר לצ'אר דינו כמערך של צ'אר (או להיפך?... התבלבלתי כבר), מה שכידוע לא נכון.
_____________________________________
נכון אתם אנשים כשרים, אך לא לזאת הייתה כוונתי. רציתי שתהיו כחיות הנוהמות ביער לילות שלמים.


נערך לאחרונה ע"י fritz2 בתאריך 04-03-2012 בשעה 16:45.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #28  
ישן 04-03-2012, 17:17
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 27 שנכתבה על ידי fritz2 שמתחילה ב "הבנתי, תודה על ההסבר..."

פשוט מאוד, כל פעם שאתה מתאחל פוינטר להצביע ל-string literal, תגדיר אותו כקונסט:
const char * str1 = "Hello";
עכשיו, לא תצליח לכתוב אליו בטעות: http://ideone.com/84IAp

הקוד לא מתקמפל, כי strcpy רוצה שהפרמטר הראשון (dst) יהיה char *‎, אבל אני מעביר אליו const char *‎. אם תקמפל את זה ב-C באתר שהבאתי תראה שהקוד עובר - זה באג מטומטם שמאפשר להמיר באופן שקוף מ-const ללא-const (למיטב זכרוני, באג בשפה ולא בקומפיילר). עדיין יש באג ב-C++‎ שלא מחייב אותך להגדיר את המצביע ככה, אבל אם תגדיר את המצביע ככה, לא תצליח להעביר אותו לפונקציה כמו strcpy בטעות.

אם אתה רוצה להעתיק מחרוזות (strcpy), לשרשר מחרוזות (strcat) או לעשות כל דבר אחר איתן שיש בו כתיבה ולא רק קריאה, כל מה שאתה צריך לעשות זה או
  • להשתמש במערך אמיתי
או:
  • להקצות זיכרון שניתן לכתיבה (באמצעות malloc).
הקוד הבא משתמש במערך, ועובד מצוין: http://ideone.com/h3PfC
הקוד הבא מקצה את הזיכרון דינאמית, וגם עובד מצוין: http://ideone.com/Y5P4i

אין בעיה במצביעים ל-char. הבעיה יכולה להיות רק במקום אליו הם מצביעים.
אם היית מגדיר משתנה בסגנון char * str1 = (char*)0x12345678 ומנסה לעשות אליו strcpy, היית מופתע שזה קורס?
זה פחות או יותר אותו דבר - המצביע שלנו הצביע לזיכרון שלא הקצנו ואסור לנו לכתוב אליו. אולי במקרה בכתובת 0x12345678 יש בלוק זיכרון שבדיוק הקצנו ב-malloc הקודם ולכן זה יפעל, ואולי לא...




בקשר לשאלה שהוספת:

מצביע ל-char ומערך של char-ים אלה דברים שונים.
לעומת זאת, כשמעבירים לפונקציה מערך של char-ים הוא מתנוון למצביע ל-char הראשון במערך.
הפרקים על מצביעים, מערכים ומחרוזות ב-c-faq.com יענו לך על כל השאלות האלה.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

אמר פסטן: שניהם גרועים, אבל עדיף להיות טיפש מאשר שקרן.
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה


נערך לאחרונה ע"י פסטן בתאריך 04-03-2012 בשעה 17:20.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 07:10

הדף נוצר ב 0.08 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר