ahmed.o.mohamed

اختبر قدراتك في C/CPP - الحلقة الثالثة, الجزء الأول

9 ردود في هذا الموضوع

السلام عليكم

الحلقة الأولى.

الحلقة الثانية - الجزء الأول.

الحلقة الثانية - الجزء الثاني.

الحلقة الثانية - الجزء الثالث.

الحلقة الثانية - الجزء الرابع.

الحلقة الثانية - الجزء الخامس.

الحلقة الثانية - الجزء السادس و الأخير.

مرحبا بكم إخوتي الكرام في الجزء الأول من الحلقة الثالثة من سلسلة اختبر قدراتك, قمتُ بتقسيم الحلقة الثالثة إلى عدة أجزاء, مُرتبة حسب الصعوبة. أجزاء هذه الحلقة ستكون خاصة بالتعامل مع الملفات.

نبدأ على بركة الله بسؤال بسيط :happy:

الإختبار الثالث (الجزء الأول) :

اكتب برنامج يطلب من المستخدم إدخال مسار ملف معين ثم يُظهر المعلومات التالية على الشاشة :

  • عدد الحروف الموجودة في الملف.
  • عدد المرات التي ظهر فيها كل حرف. (نفترض أن الحروف الأبجدية صغيرة small)
  • الأرقام و الأحرف الغير أبجدية يتم إظهارها بشكل مستقل (باعتبارها تمثل نوعا واحداً).
  • عدد الكلمات الموجودة في الملف بالإضافة إلى عدد الأسطر.

للتبسيط, نفترض أنه يتم فصل الكلمات بــ : نهاية السطر أو المسافة البيضاء أو رموز التنقيط (: , . ; ? !) أو الأقواس أو علامات الإقتباس (" or '), فقط !

مثال : (الملف التجريبي في المرفقات)

post-219439-024625200 1347059500_thumb.p

سأضع حل السؤال بعد إنتهاء عرض المحاولات.

VBXCTLX.CPP

تم تعديل بواسطه أحمد الشنقيطي
إرفاق الملف التجريبي.
3

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الكود:

#include<stdio.h>
#include<conio.h>

int main() {
char prevChar = 0, c, path[256] = "D:\\VBXCTLX.CPP";
int ascii[256] = {0}, lines = 1, words = 0, allChars = 0, otherChars = 0;
FILE *F = fopen(path, "rb");
for(c = fgetc(F); c != EOF; prevChar = c, c = fgetc(F)){
ascii[c] += (c>='a'&&c<='z')?1:0;
otherChars += (((c<'A'||c>'Z')&&(c<'a'||c>'z'))&&c!=10&&c!=13)?1:0;
allChars += (c==10||c==13?0:1);
lines += (c==13?1:0);
if(c==' '||c=='\t'||c==13||c==':'||c=='.'||c=='?'||c=='!'||c=='('||c==')'||c=='\''||c=='\"')
if(prevChar!=' '&&prevChar!='\t'&&prevChar!=13&&prevChar!=':'&&prevChar!='.'&&prevChar!='?'&&prevChar!='!'&&prevChar!='('&&prevChar!=')'&&prevChar!='\''&&prevChar!='\"')
words ++;
}
fclose(F);
printf("file: %s\n", path);
printf("number of lines = %d\n", lines);
printf("number of words = %d\n", words);
printf("number of characters = %d\n", allChars);
for(c = 'a'; c <= 'z'; c++)
printf("number of '%c' = %d\n", c, ascii[c]);
printf("number of other characters = %d\n", otherChars);
getch();
return 0;
}

لكن النتيجة مختلفة عن نتيجتك:

file: D:\VBXCTLX.CPP
number of lines = 146
number of words = 528
number of characters = 3427
number of 'a' = 100
number of 'b' = 36
number of 'c' = 60
number of 'd' = 64
number of 'e' = 170
number of 'f' = 17
number of 'g' = 51
number of 'h' = 36
number of 'i' = 120
number of 'j' = 0
number of 'k' = 0
number of 'l' = 101
number of 'm' = 19
number of 'n' = 100
number of 'o' = 137
number of 'p' = 60
number of 'q' = 0
number of 'r' = 84
number of 's' = 79
number of 't' = 129
number of 'u' = 57
number of 'v' = 36
number of 'w' = 48
number of 'x' = 33
number of 'y' = 6
number of 'z' = 0
number of other characters = 1144

حتى نتفق, السطر الأول من الملف فيه كلمة واحدة, حسب قوانينك, و السطر الثاني فيه 3 كلمات أم لا؟

//----------------------------------------------------------------------------
#include <owl\owlpch.h>

أيضا, القيمتين 13 و 10 في جدول ascii لم أحتسبهما مع الحروف الغير ابجدية

أي أن بعد أول سطر يكون عندنا 78 حرف, لكن لو احتسبناهم راح يصيرو 80 حرف قبل ما نوصل للـ # في السطر الثاني

تم تعديل بواسطه أحمد الشنقيطي
دمج المشاركات.
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أعتذر عن متابعة حلقات المسابقة .. بالكاد وصلت إلى هذا المكان لأضع حلي ..ولأعتذر .. لا أدري ربما يمكنني وربما لا ...

على كل حال ..

هذه محاولتي ... أهم شيء حاولت أن أركز عليه أن يكون الكود واضح تماما للجميع ,,,

قمت بعمل كائن وحيد من الصف ... والباقي يمكن للجميع فهمه بإذن الله .....

ولذلك فهو قابل للتطوير ...حيث كنت أتوقع أن يرفدنا الأخ أحمد بالمزيد في نفس البرنامج ..

على أي حال .. سأعمل جهدي للمتابعة ...

ملاحظة كتبت العبارات بالفرنسية .. laugh.gif


#include<cstdio>
#include<cctype>
class FileInformation
{
public:
char Path[200];
FILE*file;
unsigned int Lines;
unsigned int Letters;
unsigned int Non_letters;
unsigned int TimesRepeated[26];
unsigned char WordSeparateSymbols[12];
unsigned int Words;
FileInformation()
{
unsigned char WordSeparateSymbols2[]={ '(', ':', ',' ,'.' ,';', '?', '!', ')' ,'"' ,'\'',' ','\n' };
Lines=0;
Letters=0;
Non_letters=0;
Words=0;
for(int i=0;i<12;i++)
WordSeparateSymbols[i]=WordSeparateSymbols2[i];
for(int j=0;j<26;j++)
TimesRepeated[j]=0;
}
int GetPath();
int GetInfo();
int ShowResults();
bool isAhmadspace(char a)
{
int i=0;
while(i<12)
if(a==WordSeparateSymbols[i])return 1;
else i++;
return 0;
}
}Global;
int main()
{
if(Global.GetPath())
{
Global.GetInfo();
Global.ShowResults();
}
else
main();
return 0;
}
int FileInformation::GetPath()
{
printf("donnez le nom du fichier a examiner : ");
scanf("%s",Global.Path);
if(fopen(Global.Path,"r"))// have you saied the truth ?? :D
return 1;
else
{
printf("File Is Not Exist\nProgram Will restart ....");
return 0;
}
}
int FileInformation::GetInfo()
{
char flags[2]={0,0};//flags used to test if isthere a letter after : space,linefeed;
char buffer;
char Buf[1000];
file=fopen(Path,"rb");
while(!feof(file))
{
buffer=fgetc(file);putchar(buffer);
if(isAhmadspace(buffer))
{
Non_letters++;
flags[0]=1;
if(buffer=='\n')
flags[1]=1;
}
else
{
if(flags[0])
{
Words++;
flags[0]=0;
}
if(flags[1])
{
Lines++;
flags[1]=0;
}
if(islower(buffer))
{
TimesRepeated[buffer-'a']++;
Letters++;
}
else
Non_letters++;
}
}
return 0;
}
int FileInformation::ShowResults()
{
printf("votre fichier contient %u lignes, %u mots\n",Global.Lines,Global.Words);
printf("et %u caractetes dont :\n",Global.Letters + Global.Non_letters);
for(int i=0;i<26;i++)
{
printf("%u fois la lettre %c\n",TimesRepeated[i],'a'+i);
}
printf("et %u autres caracteres",Global.Non_letters);
return 0;
}

والنتيجة مطابقة لنتيجة ياسين .. ولكن عدد الكلمات مختلف

حيث أنني اعتبرت أي رمز مفرد هو كلمة يعني 8 كلمة و : كلمة .. وهكذا أي شيئ مفصول بفراغ عن يمينه وشماله هو كلمة ...

وكذلك اعتبرت كل حرف ليس من الأبجدية بالحروف الصغيرة هو من ضمن (بقية الحروف )والتي نعرضها في آخر البرنامج

بالتوفيق للجميع وشكرا لكم جميعاً ... والسلام عليكم ورحمة الله وبركاته

تم تعديل بواسطه مصطفى 36a2
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

هذه محاولتي أخي أحمد

#include <stdio.h>
#include <stdlib.h>

// include <ctype.h> pour toupper()

int main()

{

FILE* FICHIER=NULL;
char NOM_FICH[30];
int t[31]={0},c=0;
long s=0;
const char *str="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf("Nom du fichier texte : ");
scanf("%s", NOM_FICH);
FICHIER = fopen(NOM_FICH, "r");
if (!FICHIER)
printf("\aERREUR: Impossible d'ouvrir "
"le fichier: %s.\n", NOM_FICH);

while((c=fgetc(FICHIER))!=EOF)

{

s++;

switch(c)

{

case 'a': case 'A': t[0]++; break;
case 'b': case 'B': t[1]++; break;
case 'c': case 'C': t[2]++; break;
case 'd': case 'D': t[3]++; break;
case 'e': case 'E': t[4]++; break;
case 'f': case 'F': t[5]++; break;
case 'g': case 'G': t[6]++; break;
case 'h': case 'H': t[7]++; break;
case 'i': case 'I': t[8]++; break;
case 'j': case 'J': t[9]++; break;
case 'k': case 'K': t[10]++; break;
case 'l': case 'L': t[11]++; break;
case 'm': case 'M': t[12]++; break;
case 'n': case 'N': t[13]++; break;
case 'o': case 'O': t[14]++; break;
case 'p': case 'P': t[15]++; break;
case 'q': case 'Q': t[16]++; break;
case 'r': case 'R': t[17]++; break;
case 's': case 'S': t[18]++; break;
case 't': case 'T': t[19]++; break;
case 'u': case 'U': t[20]++; break;
case 'v': case 'V': t[21]++; break;
case 'w': case 'W': t[22]++; break;
case 'x': case 'X': t[23]++; break;
case 'y': case 'Y': t[24]++; break;
case 'z': case 'Z': t[25]++; break;
case '\n': t[26]++; break;
case ' ': t[27]++; t[28]++; break;
case ':': case '.': case ',': case ';': case '?': case '!': case '\'': case '\"': t[28]++;
default : t[29]++; break;
}

}

printf("\n\nvotre fichier contient %d ligne%c, %d mot%c et %ld caractere%c dont:\n\n"
,t[26],t[26]>1?'s':' ',t[28]+1,t[28]>0?'s':' ',s-t[26]-t[27],s-t[26]-t[27]>1?'s':' ');

for(t[30]=0;t[30]<26;t[30]++)

printf("%c\t repeter %8d foi%c\n",str[t[30]],t[t[30]],t[t[30]] > 1?'s':' ');

printf("\n\net %d autres caracteres\n",t[29]+t[28]-t[27]);

fclose(FICHIER);

return 0;
}

E8398990.jpg

وبالتوفيق للجميع

تم تعديل بواسطه مومو (momo)
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

محاولتي :

#include <stdbool.h>
#include <stdio.h>
#define LNOMFICH 20

int main() {
int sep(char);
char nomfich [LNOMFICH + 1];
FILE * entree;
char c;
int compte [26], numl, ntot, nautres, nmots, nlignes, mot_en_cours, i;

do {
printf("Donnez le nom du fichier à examiner : ");
gets(nomfich);
if ((entree = fopen(nomfich, "rt")) == NULL)
printf("Fichier non trouvé !\n");
} while (entree == NULL);

for (i = 0; i < 26; i++)compte[i] = 0;
ntot = nautres = nmots = nlignes = 0;
mot_en_cours = false;

while (c = fgetc(entree), !feof(entree)) {
if (c == '\n') nlignes++;
else {
ntot++;
numl = c - 'a';
if (numl >= 0 && numl < 26) compte[numl]++;
else nautres++;
}
if (sep(c)) {
if (mot_en_cours) {
nmots++;
mot_en_cours = false;
}
} else mot_en_cours = true;
}
fclose(entree);

printf("\nVotre fichier contient %d lignes, %d mots\n", nlignes, nmots);
printf("et %d caractères dont :\n", ntot);
for (i = 0; i < 26; i++)printf("%d fois la lettre %c\n", compte[i], 'a' + i);
printf("\net %d autres caractères\n", nautres);

return 0;
}

int sep(char c) {
char sep[12] = {'\n', ' ', ',', ';', ':', '.', '?', '!', '(', ')', '"', '\''};
int nsep = 12, i;
i = 0;
while (c != sep[i] && i < nsep) i++;
if (i == nsep) return 0;
else return 1;
}

@ياسين

قد يكون سبب اختلاف النتائج عائد إلى أنني أحسب الحروف الغير مرئية, انظر هذا المثال : ( أظهرتُ نهاية السطر عمداً )

post-219439-048800900 1347108796_thumb.p

الملف يحتوي على 14 حرف, منهم 6 حروف أبجدية و 8 حروف غير أبجدية (أرقام + رموز تنقيط + رموز غير مرئية) :

post-219439-074224600 1347108804_thumb.p

تم تعديل بواسطه أحمد الشنقيطي
Mise à jour
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
if ((entree = fopen(nomfich, "rt")) == NULL)

ماذا تعني rt???? أعرف r ,r+,rb فقط !!

وهذه أيضاً ..

 while (c = fgetc(entree), !feof(entree))

الفاصلة بينهما هل تشبه && ..من ناحية التنفيذ ؟؟

تم تعديل بواسطه مصطفى 36a2
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الحروف الغير مرئية, 10 و 13 لم أحتسبها في تعداد كل الحروف و لا الحروف الغير أبجدية

هذا التصريح يعطيك مصفوفة أصفار مباشرة

int compte [26] = {0}

عداد الأسطر قيمته الابتدائية تكون 1 لأنه عند مصادفة أول '\n' فراح ننزل للسطر الثاني و يكون عندنا سطرين

لكن أنت تقوم باحتساب الحروف A..Z على أنها رموز أخرى

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

هذه محاولتي

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct char_state{
char character;
int count;
}char_state;
typedef struct char_state_list{
char_state * list_ptr;
int size;
int lines;
int none_alpha_char;
int words;
int total_char;
}char_state_list;

typedef struct boolean{
int boolean;
int pos;
}boolean;
char_state_list getFileState(char * file_name);
boolean checkCharInStr(char key, char_state * list, int size);

int main(int argc, int **argv)
{
int i = 0;
char_state_list list = getFileState("VBXCTLX.cpp");
char_state * ptr = NULL;
ptr = list.list_ptr;
printf("Number of lines : %d\n",list.lines);
printf("Number of words : %d\n",list.words);
printf("Number of character : %d\n", list.total_char);
for(i = 0; i < list.size; i++)
{
printf("Number of : %c = %d \n",ptr[i].character, ptr[i].count);

}
return 0;
}
char_state_list getFileState(char * file_name)
{
FILE * file_ptr = NULL;
char_state * char_list = NULL, * ptr = NULL;
char_state_list list;
boolean bool_check;
bool_check.pos = 0;
int check = 0, lines = 0;
int word_count = 0, none_alpha_char = 0;
int size = 0, total_char = 0;
char c = 0;

file_ptr = fopen(file_name, "r");
while((c = fgetc(file_ptr)) != EOF)
{
total_char++;
if(c == '\n')
{
lines++;
}
if(isalpha(c))
{
check = 1;
bool_check = checkCharInStr(c, char_list, size);
if(bool_check.boolean == 0)
{
size++;
char_list = (char_state *) realloc(char_list, sizeof(char_state) * size);
ptr = char_list;
if(char_list == NULL)
{
printf("Allocation fialled\n");
free(ptr);
exit(0);
}
char_list[size - 1].character = c;
char_list[size - 1].count = 0;
bool_check.pos = size - 1;
}


char_list[bool_check.pos].count++;

}
else
{
if(check)
{
word_count++;
check = 0;
}
none_alpha_char++;
}
}
list.list_ptr = char_list;
list.size = size;
list.none_alpha_char = none_alpha_char;
list.words = word_count;
list.lines = lines;
list.total_char = total_char;
return list;
}
boolean checkCharInStr(char key, char_state *list, int size)
{
int i = 0;
boolean check;
check.boolean = 0;
check.pos = 0;
for(i = 0; i < size; i++)
{
if(list[i].character == key)
{
check.boolean = 1;
check.pos = i;
break;
}
}
return check;
}

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ماذا تعني rt ؟ أعرف r ,r+,rb فقط !!

توجد عدة أنماط للتعامل مع الملفات, أشهرها :

"rb" => Read-only, binary mode

"rt" => Read-only, text mode

"wb" => Write-only, binary mode

"wt" => Write-only, text mode

"r+t" => Read / write, text mode

"r+b" => Read / write, binary mode

"a+t" => Adding, text mode

"a+b" => Adding, binary mode

وهذه أيضاً :

while (c = fgetc(entree), !feof(entree))

بشكل عام, الكتابة التالية :

#include <stdio.h>

int main() {
int n;
do {
} while (printf("Donnez un nombre > 0 : "), scanf("%d", &n), n <= 0);
return 0;
}

تُكافئ :

#include <stdio.h>

int main() {
int n;
do
printf("Donnez un nombre > 0 : ");
while (scanf("%d", &n), n <= 0);
return 0;
}

و تُكافئ أيضا :

#include <stdio.h>

int main() {
int n;
do {
printf("Donnez un nombre > 0 : ");
scanf("%d", &n);
} while (n <= 0);
return 0;
}

لكن أنت تقوم باحتساب الحروف A..Z على أنها رموز أخرى

و هذا هو المطلوب لأن نص التمرين يفترض أن الحروف الأبجدية صغيرة small.

تم منح النقاط للمشاركات المفيدة و حذف الردود الغير مفيدة, حفاظا على تنسيق الموضوع.

يُغلق.

أراكم في الجزء الثاني من الحلقة الثالثة.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .