קריאת HEX ב C++

niminet

New member
קריאת HEX ב C++

אני מנסה לקרוא קובץ בייט אחרי בייט ולעשות כמה חישובים על הבייטים. בכל אופן, יש לי בעיה בקליטה של המידע. ההמרה בין HEX ל DEC הולכת בסדר כשהספר הראשונה בבייט היא ספרה ולא אות, אבל במקום A4, שבדצימלי זה 164, אני מקבל ב cout תוצאה משונה: ffffffa4 שלפי המחשבון זה מספר עצום בלי פרופורציה וב cout זה מינוס 92. אני מנסה לקלוט כך:
unsigned long i,size; long sum; char tmp1,tmp2; int itmp1,itmp2; ifstream file ("file.txt", ios::in|ios::binary|ios::ate);//A file created by a hex editor with 4 bytes. will have more once I get it working. size = file.tellg(); file.seekg (0, ios::beg); for(i=0,sum=0;i<size-1;i++){ file.seekg (i, ios::beg); file.read (&tmp1, 1); file.seekg (i+1, ios::beg); file.read (&tmp2, 1); itmp1=tmp1; itmp2=tmp2; cout.unsetf( ios::hex ); cout.setf( ios::dec ); cout<<itmp1<<'*'<<itmp2<<':'; cout.unsetf( ios::dec ); cout.setf( ios::hex ); cout<<itmp1<<'*'<<itmp2<<endl; sum+=itmp2*itmp1; } file.close();​
 

niminet

New member
אני לא יודע אם מותר להקפיץ פה,

בכל אופן, אני אף פעם לא מקפיץ.
 

vinney

Well-known member
סימן

תעשה במקום INT בהגדרות משתנים UNSIGNED. ובכלל, אם אתה קורא בית מקובץ, למה המשתנה שלך הוא מסוג INT? זה יותר מבית פעם אחרונה שאני בדקתי... תשתמש בUNSIGNED CHAR וכל הבעיות שלך יפטרו אוטומטית.
 

niminet

New member
כבר ניסיתי

אני משתמש בקומפיילר של Dev CPP והוא אומר:
invalid conversion from unsigned char* to char*​
 

IdanR

New member
כמה הערות..

אתה יכול לכתוב את אותו קוד בצורה קצת יעילה יותר, בהרבה פחות קוד. א. ההגדרה של משתני int נוספים, והשמה למשתנה מסוג int מיותרת, ממילא כאשר אתה עושה חישוב על משתנה מסוג char מתבצעת הסבה אוטומטית לint. (הקומפיילר לא באמת יודע לבצע חישובים על משתנים מסוג char).. אבל sum באמת צריך להיות int או long. ב. אני אישית מעדיף במקרה את זה את printf בהרבה על פני cout... ואז יש לך גם יותר שליטה על הpadding, אתה יכול לעשות למשל פורמט כזה: printf("%02x", number) מה שידפיס לך מספר הקסדיצמלי שיהיה תמיד עם שני ספרות. (ייצוג של בית אחד). ואז אתה גם לא חייב שהפרמטר number יהיה int, כי הייחוס הוא לפי הפורמט, כמו שצריך, ולא לפי הoverloading של האופרטור >>. זה גם חוסך לך כבר מה שורות קוד מיותרות. ג. השימוש בseekg מיותר, ממש אין צורך לשנות את הfile pointer אם אתה עושה מעבר סדרתי על הקובץ. חוסך לך שורות קוד מיותרות נוספות.
 

IdanR

New member
נ.ב

במקום size ולולאת for, יכולת פשוט לקרוא כל עוד לא eof.
 

niminet

New member
אני מצטער

עד עכשיו לא התעסקתי ב input מקבצים. בכל אופן, ממה שאני יודע EOF זה פשוט character עם ASCII של 26, לא? הבייט האחרון בקובץ הגדול לא בהכרח יהיה EOF. אני אנסה את העצות שלכם. תודה.
 

vinney

Well-known member
EOF זה לא פשוט תו

אתה לא קורא תו 26 מקובץ ומחליט שזה EOF, מערכת ההפעלה אומרת לך מתי הגעת לסוף הקובץ, ובכלל לא על בסיס איזה תו נקרא. דבר שני, זה מה שקורא כשלומדים CPP בלי ללמוד C קודם. תקרא על fscanf וprintf, כל מה שכתבת עם שתי הפקודות האלה ניתן לעשות בשתי שורות.
 

IdanR

New member
אין על מה להצטער.

פשוט קבל זאת כביקורת בונה.
 

niminet

New member
אוקיי ישמתי את העצות,

אבל זה עוד לא פותר לי את הבעיה שהוא פשוט לא מקבל את המידע הנכון. בקשר ל seekg, מחקתי חלק אבל השארתי שורה אחת עם הפקודה בגלל שאין לי חשק ללמוד כרגע הזזה של הסמן באופן יחסי ואני מבין שזה עניין של נוחות ואולי יעילות שולית. הנה הקוד הנוכחי:
unsigned long i,size; long sum; char tmp1,tmp2; ifstream file ("file.txt", ios::in|ios::binary|ios::ate); size = file.tellg(); file.seekg (0, ios::beg); printf("File size: %d bytes\n",size); for(i=0,sum=0;i<size-1;i++){ file.seekg (i, ios::beg); file.read (&tmp1, 1); file.read (&tmp2, 1); printf("%02x*%02x\n", tmp1,tmp2); sum+=tmp2*tmp1; } file.close(); printf("sum=%d\n",sum);​
הפלט בבייט שערכו A4 עדיין מוצג כ ffffffa4, ובהמרה לדצימלי מינוס 92.
 

niminet

New member
ועם eof

עדיין אותה בעיה:
unsigned long i,size; long sum; char tmp1,tmp2; ifstream file ("num.net", ios::in|ios::binary); sum=0; while(!file.eof()){ file.read (&tmp1, 1); file.read (&tmp2, 1); file.seekg(-1, ios::cur); printf("%02x*%02x\n", tmp1,tmp2); sum+=tmp2*tmp1; } file.seekg(-1, ios::cur); file.read (&tmp1, 1); sum-=tmp1*tmp1; file.close(); printf("sum=%d\n",sum); system("PAUSE"); return 0;​
 

niminet

New member
עוד לא סיימתם איתי../images/Emo3.gif

אף פעם לא ניסיתם לפרק קובץ בינארי לבייטים?
 

vinney

Well-known member
לא יישמת את ההמלצות

המשתנים שלך לא unsigned, אתה מדפיס עם %d במקום %u, ואתה לא מאפס משתנים באיתחול.
 
למעלה