الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

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

مغلق
بدأه Snack3r في 7 سبتمبر 2012 · 8 رد · 1,143 مشاهدة · في اختبر قداراتك
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

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

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

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

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

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

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

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

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

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

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

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

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

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

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

post-219439-024625200 1347059500_thumb.p

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

VBXCTLX.CPP

المرفقات
Test.png

تم تعديل هذه المشاركة بواسطة أحمد الشنقيطي في 8 سبتمبر 2012 في 02:12 — السبب: إرفاق الملف التجريبي.

3
#2

الكود:

#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 حرف قبل ما نوصل للـ # في السطر الثاني

تم تعديل هذه المشاركة بواسطة أحمد الشنقيطي في 8 سبتمبر 2012 في 18:35 — السبب: دمج المشاركات.

[سبحان الله و بحمده, سبحان الله العظيم]

#3

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

على كل حال ..

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

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

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

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

ملاحظة كتبت العبارات بالفرنسية .. 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=WordSeparateSymbols2;
		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)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,'a'+i);
	}
	printf("et %u autres caracteres",Global.Non_letters);
	return 0;
}

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

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

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

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

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 8 سبتمبر 2012 في 13:00

#4

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

#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) في 8 سبتمبر 2012 في 13:10

i love you mama

#5

السلام عليكم

محاولتي :

#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 = 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, '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 < 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
المرفقات
imgTest.pngcodeTest.png

تم تعديل هذه المشاركة بواسطة أحمد الشنقيطي في 8 سبتمبر 2012 في 17:58 — السبب: Mise à jour

#6
اقتباس
if ((entree = fopen(nomfich, "rt")) == NULL)

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

وهذه أيضاً ..

اقتباس
 while (c = fgetc(entree), !feof(entree))

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

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 8 سبتمبر 2012 في 16:06

#7

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

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

int compte [26] = {0}

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

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

[سبحان الله و بحمده, سبحان الله العظيم]

#8

السلام عليكم

هذه محاولتي

#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.character, ptr.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.character == key)
    	{
        	check.boolean = 1;
        	check.pos = i;
        	break;
    	}
	}
	return check;
}
#9
اقتباس
ماذا تعني 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.

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

يُغلق.

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

هذا الموضوع مغلق.

مواضيع مشابهة