c++ - הדפסה למסך בעברית?

c++ - הדפסה למסך בעברית?

היי, אני עובד תחת windows.
אני מעוניין להדפיס על המסך גם תווים ומחרוזות בעברית.
קראתי על wchar_t, CHART - בינתים לא הצלחתי להדפיס למסך\לקובץ בעברית.
אשמח לעזרה
 

BravoMan

Active member
למסך כנראה גם לא תצליח...

מזמן לא עבדתי על Windows, אבל לפי מה שזכור לי, הבדיחה העצובה שקוראים לה Console ("מסוף") במערכת הזו לא ממש אוהב תווים שאינם באנגלית.
לגבי הקובץ, זה כנראה נכתב בקידוד שונה ממה שיצרת בתוכנה.
&nbsp
תוריד Notepad++ (זה בחינם) תפתח את הקובץ שנוצר, ונסה לשחק עם הקידודים.
בנוסף, תכתוב כאן מה גרסת VS בה אתה משתמש, מה גרסת Windows ומה הן בדיוק ההגדרות האזוריות של המערכת שלך.
 
לקובץ הוא מוציא חלק בעברית וחלק ג'יבריש.

עשיתי בקובץ convert utf8 without bom. גם השאר נתנו אותה תוצאה.
אני אגיד לך מה, אני בעיקרון פחות מעניין אותי המסך או אפילו הקובץ.
יש לי תוכנית שכתבתי ב-C++ שהיא ניגשת לשרת שלי לקובץ TXT (פותחת סוקט, שולחת HTTP וכו') ועושה על הטקסט הזה בדיקה כדוגמאת: בודקת אם המילה "עבודה" קיימת בקובץ או לא.

מכיוון שזה מילה בעברית התוכנית מחזירה שהיא לא מוצאת.. אבל אם המילה איתה באנגלית זה היה עובד..
איך אני יכול להתגבר על הבעיה הזו (לצורך העניין כרגע ב-windows)?
 

BravoMan

Active member
אז זו שאלה אחרת לגמרי...

קדום כל, צריך להחליט באיזה קידוד שמור הקובץ המקורי בשרת שאתה מוריד.
דבר שני, תראה את הקוד שאחראי לקרוא ממנו.
&nbsp
כשמדובר בתקשורת, יכולה להיווצר בעיה, כי הקובץ נשלח בחתיכות, ובגלל שבקידודי Unicode על גרסאותיהם אותיות עבריות נשמרות בתור 2 בתים לפחות, יש אפשרות שאות מסוימת תישבר באמצע, ותשבור את שאר האותיות שאחריה.
&nbsp
תראה גם את הקוד שמחפש את המילה, ייתכן שהוא זה שלא יודע להתמודד עם הקידוד.
 
הקוד + הסברים

החלק הרלוונטי בקוד שמקבל את הנתונים:
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) { printf("Bytes received: %d\n", iResult); fprintf(file, "%s", recvbuf); if (strstr(recvbuf, pattern) != 0) flag = true; } else if (iResult == 0) printf("Connection closed\n"); else printf("recv failed with error: %d\n", WSAGetLastError());} while (iResult > 0);

recvbuf הוא בגודל 512.
בנוסף, הקובץ שעל השרת הוא בקידוד utf8.
בקוד הזה באמת ייתכן שאני "שובר" אותיות שהם בעברית. הדרך שאני חושב להתגבר על הבעיה היא באמצעות מחרוזת שאליה כל הזמן אני אשרשר את recvbuf
 

BravoMan

Active member
אכן, הדבר הנכון לעשות הוא להוריד את כל הקובץ

ל-buffer כלשהו או לקובץ מקומי שתוכל אחרכך לטעון ל-buffer בחתיכה אחת, ורק אז לחפש.
&nbsp
אבל אם אתה משתמש אובייקט string או חלופה דומה של MS, קרא קודם על ההתנהגות שלו.
אם הוא יותר ממעטפת למערך של char, ייתכן שהוא בודק מה אתה דוחף לתוכו, ואם יקבל תו "חתוך" שאינו חוקי, יתעלם ממנו ויגרום לחורים או יזרוק exception ויביא לקריסת התוכנה.
 
יש התקדמות, אבל עדין בחלק מהטקסט מקבל ג'יבריש

אני כרגע רק בשלב של לקחת את הפלט שקיבלתי מהשרת ולהעביר אותו לקובץ.
צרפתי תמונה שמראה שבחלק מהטקסט מקבל ג'יבריש.
לא מצליח להבין היכן הטעות.
להלן החלק הרלונטי בקוד שמראה כיצד אני מקבל את הנתונים, משרשר את הנתונים ל-str_return שהוא יחזיק לי את הפלט (אגב, לא יודע אם ב-C++ יש חלופה ל-realloc).
בסופו של דבר לאחר שהפעולה מסחיימת אני מחזיר את str_return ובתוכנית הראשית אני פשוט כותב לקובץ את הפלט הזה.
int curr_size_str_return = 1;char* str_return = (char *)malloc(curr_size_str_return);
strcpy_s(str_return, curr_size_str_return, "");
// Receive until the peer closes the connectiondo { iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); // Bytes received if (iResult > 0) { printf("Bytes received: %d\n", iResult); str_return = (char *)realloc(str_return, curr_size_str_return=(curr_size_str_return + recvbuflen)); strcat_s(str_return, curr_size_str_return, recvbuf); } else if (iResult == 0) printf("Connection closed\n"); else printf("recv failed with error: %d\n", WSAGetLastError());} while (iResult > 0);return(str_return);

 
אוקי הצלחתי לפתור את הבעיה!

מה שקרה זה שחלק מהפעמים שהתבצעה קריאה לפונקציה recv, היא לא תמיד קיבלה 512 בתים, אלא פחות מכך. כתוצאה מכך, הבאפר לא היה נקי. כי התבצעה העתקה עד לחלק מסוים מהבאפר והשאר היה "מלוכלך". לכן קיבלתי ג'יבריש בחלק מהמקרים.
הפתרון: שימוש ב-strncat_s במקום strcat_s והעתקת recvbuf עד לאורך שהתקבל.
 
למעלה