-2

このコードにはエラーはありませんが、実行すると出力がなく、プログラムが動作を停止したと言ってプログラムが自動的にシャットダウンします。

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
int main()
{
char *timetoken;
char currtime[7];
char schedtime[7];
int i;
struct tm *localtimeptr;
strcpy(schedtime,"15:25:00");
while(6!=9)
{
   time_t lt;
   sleep(1);
   lt = time(NULL);
   localtimeptr = localtime(lt);
   timetoken=strtok(asctime(localtimeptr)," ");
   for(i=1;i<5;i++)
   timetoken=strtok('\0'," ");
   if(i==3)
   {
           strcpy(currtime,timetoken);
    }
}
           printf("The current time is: %s\n",currtime);
           printf("We are waiting for: %s\n",schedtime);
           if(!strcmp(currtime,schedtime))
           {
                                          printf("Time to do stuff \n");
                                          system("C:\PROJECT X");
            }        
            getch();
            return 0;                      
}
4

4 に答える 4

5

あなたが何をしようとしているのかわかりませんが、これは怪しいです:

while(6!=9)
{
   /* ... */
}
/* ... more code ... */

6 は常に 9 と等しくないため、これは無限ループです。ループから抜け出す方法がないため、「その他のコード」セクションでは何も実行されません。これは、printfが実行されず、呼び出しも実行されないことを意味しますsystem。このループから抜け出す方法が必要です。

コードを読みやすくするために (これは常に最優先事項です! )、ただ書くことをお勧めします。

while (true) {
    ...
}

ループが明示的に終了するまでループが実行されることになっていることを明確にするbreakため。

別の注意:このコード

system("C:\PROJECT X");

C++ は\Pエスケープ文字として解釈されるため、不正解です。これを修正するには、スラッシュをエスケープします:

system("C:\\PROJECT X");

別のバグについては、次のループをよく見てください。

   for(i=1;i<5;i++)
   timetoken=strtok('\0'," ");
   if(i==3)
   {
       strcpy(currtime,timetoken);
   }

C++ はこれを次のように解釈しています。

   for(i=1;i<5;i++) {
       timetoken=strtok('\0'," ");
   }

   if(i==3)
   {
       strcpy(currtime,timetoken);
   }

ここから、ifステートメントがループの外にあるため、これが機能しないことは明らかです。したがって、i決して 3 ではありません。

   for(i=1;i<5;i++) {
       timetoken=strtok('\0'," ");
       if(i==3)
       {
           strcpy(currtime,timetoken);
       }
   }

コードのフォーマット (インデント、空白など) をきれいにする努力をすると、この種のエラーを防ぐのに役立ちます。for ループに対して local として宣言していた場合はi、おそらくこれを以前に見つけていたでしょう。たとえば、次のコードはコンパイルされません。

   for(int i = 1; i < 5; i++) {
       timetoken=strtok('\0'," ");
   }

   if(i==3) // i is not in scope
   {
       strcpy(currtime,timetoken);
   }

原則として、絶対に必要になるまで変数の宣言を延期します。これにより、コードが読みやすくなり (使用中の変数は、それらを使用しているコードに近い傾向があります)、バグが少なくなります (上記のように)。

これがあなたが始めるのに役立つことを願っています!

于 2012-06-21T20:54:28.283 に答える
3

投稿されたコードに関するいくつかの問題:

  • これは配列の終わりを超えて実行されます:

    strcpy(schedtime,"15:25:00");
    

    としてschedtime宣言されているように、 (8文字とnullターミネータ)char[7]である必要があります。char[9]

  • への最初の引数strtok()は であり、char*ではありませんchar:

    timetoken=strtok('\0'," ");
    

    あなたが意味したのは:

    timetoken=strtok(NULL," ");
    
  • timetokennull でないか、または に適合することを確認するチェックはありませんcurrtime

    if(i==3)
    {
        strcpy(currtime,timetoken);
    }
    

    null ポインターを渡すと、strcpy()ほぼ確実にセグメンテーション違反が発生します ( http://ideone.com/bacOG )。

于 2012-06-21T20:52:25.570 に答える
2

このシーケンスはバッファ オーバーフローです。文字列の内容とは関係のないメモリを走り書きしたため、この時点以降は何でも発生する可能性があります。(バッファ オーバーフローは、最も広範かつ簡単に悪用されるセキュリティ問題でした。)

char schedtime[7];
strcpy(schedtime,"15:25:00");

最後のASCIIバイトをschedtime含む文字列全体を保持するのに十分な長さであることを確認する必要があります. 十分であろう。NULschedtime[9]

これは、無限ループを記述する奇妙な方法です。

while(6!=9)
{
...
}

より慣用的なのはwhile (1)orfor (;;)です。それらに固執してください。他の人があなたのコードを読むのがはるかに簡単になります。

コードの詳細にはおそらく他にも間違いがありますが、問題の設計にはもっと大きな誤りがあります。無限ループで実行sleep(1)し、時間の文字列値を目標時間と照合すると、最終的にtrueと比較されると想定していますが、これは間違った想定です。1 秒間スリープ状態になるプロセスは、指定された時間が経過した後に起動される可能性があります。条件がtrueと評価される 1000 ミリ秒の間、プロセスがスリープ状態になる可能性があります。

希望の時間に対して現在の時間をチェックし、何秒離れているか、そしてsleep()全期間を把握する方がはるかに良いでしょう。タスクが最初に信号によって起動されない限り、目的の時間の 1 秒以内になります。

于 2012-06-21T21:00:29.797 に答える
1

schedtime割り当てたよりも多くのデータをコピーしています:

strcpy(schedtime,"15:25:00");

コピーされた文字列の長さは 9 文字で、7 分のスペースがあります。これ自体は問題ではないかもしれませんが、メモリがlocaltimptr関係するように配置されている場合、 で呼び出すときに終端の null 文字が存在せず、おそらく接触printf()します。scheduletimeプロセスに割り当てられていないため、エラーで終了するメモリ

于 2012-06-21T20:55:15.520 に答える