سلوك غير طبيعي للتعامل مع الملفات النصية في ج
سؤال
أحاول محاكاة سلوك خادم DNS ، الذي يطلق عليه ديسيبل hosts.txt
تحتوي machine_names/IP_addresses
, ، فمثلا:
equipo_00/169.0.1.169
sala_oeste_01/200.1.2.200
sala_oeste_02/200.2.3.200
sala_oeste_03/200.3.4.200
MEMFIS_04/201.4.5.201
ICARO_05/200.5.6.200
equipo_06/169.6.7.169
sala_este_07/201.7.8.201
sala_este_08/201.8.9.201
CEC_09/189.9.10.189
هذا هو الكود الخاص بي:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
char* machine, *ip_add;
FILE* db;
char* flag;
char tmp[256];
char par[256];
printf("> ");
scanf("%s", par);
db = fopen("hosts.txt", "r");
while(db != NULL && fgets(tmp, sizeof(tmp), db) != NULL)
{
if(strstr(tmp, par))
{
flag = "1"; // flag setting to 1 means find the line
machine = strtok(tmp, "/");//here's supposed to get the value of the machine
ip_add = strtok(NULL, "/");//here's supposed to get the value of the ip adress
}
}//while
if(strcmp(flag, "1") == 0) //
{
printf("here\n");
}
else
{
flag = "0"; //flag setting to 0
printf("there\n");
}
printf("flag= %s pc=%s server=%s\n", flag, machine, ip_add);
return 0;
}
يقرأ الكود الخاص بي من الإدخال القياسي ، وقيمة الجهاز وتشير إلى عنوان IP الذي تم تعيينه لهذا الجهاز على الخادم. المشكلة هي أن البرنامج ليس سلوكًا طبيعيًا ، ولا أعرف كيفية تعديل الكود الخاص بي إلى الإخراج المتوقع ، على سبيل المثال
input: equipo_00
output: flag = 1 pc = equipo_00 server=169.0.1.169
آسف إذا كان السؤال سخيفًا إلى حد ما ، فأنا جديد على هذه اللغة .. شكرًا لكم جميعًا على مساعدتكم وأعذر لغتي الإنجليزية
المحلول
هذا هو ما تفعله:
اقرأ سلسلة من الملف إلى tmp
.
تحقق مما إذا كان المستخدم إدخال السلسلة par
موجود في tmp
.
إذا كانت الإجابة بنعم ، فقد تقدمت وترميز tmp
على /
وجعل المؤشر machine
أشر إلى القطعة الأولى و ip_add
أشر إلى القطعة التالية.
لاحظ أن machine
و ip_add
نكون فقط مؤشرات. ويشيرون إلى مؤشرات مختلفة من tmp
. لذلك في وقت لاحق عندما تستمر مع الحلقة ، تقرأ السلسلة الجديدة مرة أخرى في tmp
, ، الكتابة فوقها. هذا يسبب المشكلة ومؤشرك يشير الآن إلى سلسلة متغيرة.
لتجنب هذا فقط أضف استراحة بعد مباراة ناجحة:
if (strstr(tmp, par)) {
flag = "1";
machine = strtok(tmp, "/");
ip_add = strtok(NULL, "/");
break;
}
أيضا النهائي الخاص بك printf
:
printf("flag= %s pc=%s server=%s\n", flag, machine, ip_add);
يجب أن يكون جزءًا من if
الجسم ، بحيث تقوم بطباعتها فقط إذا وجدت المباراة. حاليا أنت تطبع حتى إذا لم يتم العثور على المباراة. في هذه الحالة ، ستطبع غير المرغوب فيه كمؤشراتك server
و ip_add
لديك لم تتم تهيئتها.
نصائح أخرى
يبدو أن مشكلتك قد تكون مع flag
عامل. استخدام سلسلة لقيمة العلم يبدو غير عادي للغاية. جرب هذا:
int flag = 0; // always initialise your variables
if (strstr(tmp, par) == 0) {
flag = 1; // just an integer value
}
if (flag) { // easier to test the value too!
// ...
}
printf("flag=%d\n", flag); // ints use %d format value
في الكود الخاص بك أعلاه ، flag
لا يهتم المتغير في بداية الوظيفة التي قد لا تعطي نتائج غير متوقعة (وغير محددة).
فيما يلي الرمز الثابت. هناك العديد من الأخطاء البسيطة ، معظمها مفقودة. فكر في ما سيحدث إذا لم يتم العثور على الجهاز.
والآخر هو أنك تستخدم نفس المخزن المؤقت لكل تكرار للحلقة ، وبالتالي مسح الخادم الذي تم العثور عليه مسبقًا. لقد أصلحت ذلك عن طريق الخروج من الحلقة. يمكن أن تكون هناك طريقة أخرى لنسخ النتيجة التي تم العثور عليها في مخزن مؤقت آخر.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
char* machine = "";
char* ip_add = "";
FILE* db;
char* flag;
char tmp[256];
char par[256];
printf("> ");
scanf("%s", par);
db = fopen("hosts.txt", "r");
while(db != NULL && fgets(tmp, sizeof(tmp), db) != NULL)
{
char * found = strstr(tmp, par);
if(found)
{
flag = "1"; // flag setting to 1 means find the line
machine = strtok(found, "/");//here's supposed to get the value of the machine
ip_add = strtok(NULL, "/");//here's supposed to get the value of the ip adress
break;
}
}//while
if(strcmp(flag, "1") == 0)
{
flag = "0"; //flag setting to 0
}
printf("flag= %s pc=%s server=%s\n", flag, machine, ip_add);
return 0;
}
if(strcmp(flag, "1") == 0)
لا يمكنك التحقق من ذلك لأنه إذا لم يتم تهيئة العلم ، فهو سلوك غير محدد
STRCMP () يبحث عن حرف " 0" في كلتا الوسيطتين